Using RhinoMocks, how can I assert that one of several methods was called?

谁说胖子不能爱 提交于 2019-12-07 22:38:06

问题


Consider the following service interfaces:

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

public interface IServiceB
{
    void DoSomething();
}

The implementation of IServiceB depends on IServiceA like this:

public class ServiceB : IServiceB
{
    private IServiceA _serviceA;

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

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

Ie. the dependency is injected in the constructor.

Now consider a unit test for the DoSomething() method. I wish to assert that one of the overloaded DoSomething-methods in IServiceA is called, but following a general principle that unit tests shouldn't know too much about the internal workings of the method being tested, I wish to be agnostic about which of the two overloads is called. Consider the following unit test:

[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));
    }
}

How can I assert that either one or the other of the two methods was called?


回答1:


You could manually set a boolean flag like so:

[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);
    }
}

I don't think this very useful though. Unit tests are concerned with anything that is observable from outside of the component boundaries. Method calls to mocks are part of that. In other words, it is OK if you test for a specific overload being called. After all, there must be a reason why you use that overload and not the other one.

If you really want the unit test to remain ignorant of the implementation, you wouldn't be allowed to assert method calls on mocks at all. That would be a severe restriction on your ability to write tests.



来源:https://stackoverflow.com/questions/4386904/using-rhinomocks-how-can-i-assert-that-one-of-several-methods-was-called

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!