我正在按照ayende在这篇文章中描述的犀牛嘲笑中的预期.我的代码看起来像这样:
using (_mocks.Ordered())
{
Expect.Call(() => _myMock.CallA());
Expect.Call(() => _myMock.CallB(40));
Expect.Call(() => _myMock.CallA());
}
_mocks.ReplayAll();
_myObjectUnderTest.DoStuff();
_mocks.VerifyAll();
Run Code Online (Sandbox Code Playgroud)
在此之后,我想添加更多期望并测试更多我的对象的方法.我想这样做是因为我有一些基本的测试方法可以对我的测试对象进行一些设置,而且我不想重新测试那个功能,所以我只是调用早期的测试方法.如果我在VerifyAll()之后尝试添加更多期望,我会得到一个异常:"当模拟对象处于验证状态时,此操作无效."
我的部分问题是我并不真正理解所有重放/验证内容的作用,我只是复制了代码.我正在使用严格的模拟,因此任何设置代码必须具有匹配的期望或失败.我不想复制我的设置代码的期望.
有没有办法重置模拟以某种方式准备重新开始?
简短的回答:不。现在来谈谈长答案。
重放和验证的作用是这样的。在调用之前ReplayAll,您需要告诉 Rhino 您期望这些方法将要执行的操作。从某种意义上说,您正在记录对您创建的模拟对象的调用。
记录方法调用后,您可以打电话ReplayAll告诉 Rhino 您现在要做的“事情”应该执行所记录的方法。
最后,您VerifyAll调用 Rhino 来验证这些方法是否确实按照您记录的方式被调用。
现在来谈谈为什么你真的不应该重复使用模拟。对于单元测试/TDD,您的单元测试应该尽可能少地进行测试。这是为了让您的单元测试简单透明。单元测试的整体思想是将许多许多小测试作为一个整体来测试整个系统。
有关 TDD 的非常好的演示文稿解释了这一主题和其他主题,请参阅http://www.infoq.com/presentations/integration-tests-scam。
PS:一个小细节:只要方法不返回结果,你就可以写:
using (_mocks.Ordered())
{
Expect.Call(() => _myMock.CallA());
Expect.Call(() => _myMock.CallB(40));
Expect.Call(() => _myMock.CallA());
}
Run Code Online (Sandbox Code Playgroud)
作为:
using (_mocks.Ordered())
{
_myMock.CallA();
_myMock.CallB(40);
_myMock.CallA());
}
Run Code Online (Sandbox Code Playgroud)
(至少使用最新版本的Rhino)