考虑以下服务接口(interface):
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);
}
}
即。依赖项被注入(inject)到构造函数中。
现在考虑一下 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));
}
}
我如何断言这两个方法中的一个或被调用了?
最佳答案
您可以手动设置 bool 标志,如下所示:
[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);
}
}
不过我认为这不是很有用。单元测试涉及从组件边界之外可观察到的任何内容。对模拟的方法调用是其中的一部分。换句话说,如果您测试正在调用的特定重载就可以了。毕竟,您使用该重载而不是另一个重载一定是有原因的。
如果您确实希望单元测试对实现一无所知,则根本不允许您在模拟上断言方法调用。这将严重限制您编写测试的能力。
关于unit-testing - 使用RhinoMocks,我如何断言调用了几种方法之一?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4386904/