Используя RhinoMocks, как я могу утверждать, что был вызван один из нескольких методов? - PullRequest
2 голосов
/ 08 декабря 2010

Рассмотрим следующие сервисные интерфейсы:

public interface IServiceA
{
    void DoSomething(string s);
    void DoSomething(string s, bool b);
}

public interface IServiceB
{
    void DoSomething();
}

Реализация IServiceB зависит от IServiceA следующим образом:

public class ServiceB : IServiceB
{
    private IServiceA _serviceA;

    public ServiceB(IServiceA serviceA)
    {
        _serviceA = serviceA;
    }

    public void DoSomething()
    {
        _serviceA.DoSomething("Hello", true);
    }
}

Т.е.. зависимость вводится в конструктор.

Теперь рассмотрим юнит-тест для метода DoSomething(). Я хочу утверждать, что один из перегруженных DoSomething-методов в IServiceA вызывается, но, следуя общему принципу, что модульные тесты не должны знать слишком много о внутренней работе тестируемого метода, я хочу быть независимым от того, какой из две перегрузки называется. Рассмотрим следующий модульный тест:

[TestFixture]
public class ServiceBTests
{
    [Test]
    public void DoSomething_CallsServiceA()
    {
        var serviceAMock = MockRepository.GenerateMock<IServiceA>();
        var service = new ServiceB(serviceAMock);

        service.DoSomething();

        // Problem: How to check if EITHER:
        serviceAMock.AssertWasCalled(s => s.DoSomething(Arg<String>.Is.NotNull, Arg<bool>.Is.Anything));
        // OR:
        serviceAMock.AssertWasCalled(s => s.DoSomething(Arg<String>.Is.NotNull));
    }
}

Как я могу утверждать, что или один или был вызван другой из двух методов?

1 Ответ

4 голосов
/ 08 декабря 2010

Вы можете вручную установить логический флаг, например, так:

[TestFixture]
public class ServiceBTests
{
    [Test]
    public void DoSomething_CallsServiceA()
    {
        var serviceAMock = MockRepository.GenerateMock<IServiceA>();
        bool called = false;
        serviceAMock.Stub(
             x => x.DoSomething(Arg<String>.Is.NotNull, Arg<bool>.Is.Anything))
            .WhenCalled(delegate { called = true; });
        serviceAMock.Stub(x => x.DoSomething(Arg<String>.Is.NotNull))
            .WhenCalled(delegate { called = true; });

        var service = new ServiceB(serviceAMock);

        service.DoSomething();

        Assert.IsTrue(called);
    }
}

Я не думаю, что это очень полезно.Модульные тесты касаются всего, что можно наблюдать за пределами границ компонентов.Призывы к методам являются частью этого.Другими словами, все в порядке, если вы проверяете конкретную вызываемую перегрузку.В конце концов, должна быть причина, по которой вы используете эту перегрузку, а не другую.

Если вы действительно хотите, чтобы модульный тест оставался в неведении о реализации, вам не разрешили бы утверждать вызовы методаиздевается вообще.Это будет серьезным ограничением вашей способности писать тесты.

...