【问题标题】:Using RhinoMocks, how can I assert that one of several methods was called?使用 RhinoMocks,我如何断言调用了几种方法之一?
【发布时间】:2010-12-08 11:29:26
【问题描述】:

考虑以下服务接口:

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() 方法进行单元测试。我希望断言调用了 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));
    }
}

我如何断言 任一 一个 两个方法中的另一个被调用?

【问题讨论】:

  • 嗯。也许我的想法在这里有偏差。我想单元测试应该确定 DoSomething() 完全按照它应该做的。虽然该方法的内部工作与单元测试无关,但确切地知道该方法应该做什么需要,也许,确切地知道应该调用哪个重载。对此有何看法?

标签: unit-testing dependency-injection rhino-mocks assert


【解决方案1】:

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

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

我认为这不是很有用。单元测试关注从组件边界之外可观察到的任何事物。对模拟的方法调用是其中的一部分。换句话说,如果您测试调用的特定重载是可以的。毕竟,你使用那个重载而不是另一个重载肯定是有原因的。

如果您真的希望单元测试不了解实现,则根本不允许您在模拟上断言方法调用。这将严重限制您编写测试的能力。

【讨论】:

  • 是的。您可能已经在上面看到了我的评论,它反映了这些方面的认识。所以我毕竟已经为特定的调用编写了单元测试。但无论如何,谢谢你的提示。在特殊情况下可能会派上用场。
  • 我在使用 NSubstitute 时偶然发现了一个非常相似的情况。你不能争辩说调用哪个方法并不重要,只要行为相同吗?大多数时候行为驱动的测试不是更好吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多