所以我有一个类的方法如下:
public class SomeClass { ... private SomeDependency m_dependency; public int DoStuff() { int result = 0; ... int someValue = m_dependency.GrabValue(); ... return result; } }
而且我已经决定每次调用m_dependency.GrabValue()而不是每次都调用m_dependency.GrabValue(),因为我们每次都会获得相同的值(依赖关系是这样的)关闭并从几乎没有变化的表格中获取一些数据.
我遇到了问题,但试图在单元测试中描述这种新行为.我尝试了以下(我正在使用NUnit和RhinoMocks):
[Test] public void CacheThatValue() { var depend = MockRepository.GeneraMock<SomeDependency>(); depend.Expect(d => d.GrabValue()).Repeat.Once().Return(1); var sut = new SomeCLass(depend); int result = sut.DoStuff(); result = sut.DoStuff(); depend.VerifyAllExpectations(); }
然而,这不起作用;即使没有对功能进行任何更改,此测试也会通过.我究竟做错了什么?
解决方法
我认为缓存与Do(ing)Stuff正交.我会找到一种方法将缓存逻辑拉到方法之外,或者通过更改SomeDependency或以某种方式包装它(我现在对基于lambda表达式的缓存类有一个很酷的想法 – yum).
这样你的DoStuff测试不需要改变,你只需要确保它们与新的包装器一起工作.然后,您可以独立地测试SomeDependency或其包装器的缓存功能.使用架构良好的代码放置缓存层应该相当容易,您的依赖性和实现都不应该知道差异.
单元测试不应该测试实现,他们应该测试行为.同时,受试者应该有一套狭义的行为.
要回答您的问题,您使用的是动态模拟,默认行为是允许任何未配置的调用.其他调用只返回“0”.您需要设置一个期望,即不再对依赖项进行调用:
depend.Expect(d => d.GrabValue()).Repeat.Once().Return(1); depend.Expect(d => d.GrabValue()).Repeat.Never();
您可能需要输入录制/重播模式才能使其正常工作.