使用RhinoMocks,如何断言调用了几种方法之一?

Tor*_*gen 2 unit-testing assert dependency-injection rhino-mocks

考虑以下服务接口:

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

public interface IServiceB
{
    void DoSomething();
}
Run Code Online (Sandbox Code Playgroud)

IServiceB的实现取决于IServiceA,如下所示:

public class ServiceB : IServiceB
{
    private IServiceA _serviceA;

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

    public void DoSomething()
    {
        _serviceA.DoSomething("Hello", true);
    }
}
Run Code Online (Sandbox Code Playgroud)

就是 依赖项被注入到构造函数中。

现在考虑对该DoSomething()方法进行单元测试。我想断言,调用了IServiceA中的一种重载DoSomething方法,但是遵循一个普遍的原则,即单元测试对所测试方法的内部工作不应该了解太多,我希望与哪一个无关。称为两个重载。考虑以下单元测试:

[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));
    }
}
Run Code Online (Sandbox Code Playgroud)

我怎么可以断言,无论是一个另一个的两种方法被称为?

Wim*_*nen 5

您可以像这样手动设置布尔标志:

[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);
    }
}
Run Code Online (Sandbox Code Playgroud)

我认为这不是很有用。单元测试涉及从组件边界之外可以观察到的任何事物。模拟的方法调用是其中的一部分。换句话说,如果您测试是否正在调用特定的过载,则可以。毕竟,一定有理由为什么要使用该重载而不使用另一个重载。

如果您确实希望单元测试对实现一无所知,则根本不允许您对模拟进行断言方法调用。那将严重限制您编写测试的能力。