在单元测试代码中同时使用mock对象和fake对象可以吗。
示例
when(computationHelper.someMethod()).thenReturn(stringGrid.writeCell(rowNum,colNum,value));
其中computationHelper是mock对象,stringGrid是我自己的实现和一个伪对象。
是的,绝对允许在同一测试中使用各种测试替身,包括mock、fake和stub。正如androne在评论中提到的那样,您可能希望选择一个命名系统或约定来帮助您确定哪些依赖项是mock或fake,特别是为了更容易地帮助诊断测试是由于缺少mock预期还是由于实际系统故障而失败。
您也可以考虑使用真实的实现;毕竟,隔离测试中的单元的决定可能会过多,因为人们希望您可以信任JRE的实现或Mockito的实现,并且不应该试图模拟或替换它们。当它们快速、确定且测试良好时,我倾向于使用真实的实现——当它们足够简单而不需要深度依赖图时。(这需要一些判断;例如,我很想使用真正的EmailAddressParser,但可能不是真正的FullStackRpcServer。)
不过,需要注意的一点是:您可能需要提取变量的返回值。
Result result = stringGrid.writeCell(rowNum,colNum,value);
when(computationHelper.someMethod()).thenReturn(someMethodResult);
这有两个原因:
对于Mockito的新手来说,您的原始语法可能看起来像每次调用
someMethod
时都会调用writeCell
,而事实上,除非您编写自己的Answer,否则这种情况不会发生。将其提取为一个变量可以清楚地表明,当您设置when
语句时,Mockito将只对writeCell
求值一次。尽管在使用伪实现或真实现时,语法可以很好地工作,但如果
stringGrid
是mock,类似的代码可能不起作用。这是因为Mockito在很大程度上依赖于副作用和执行顺序,因此在方法的存根过程中调用mock可能会导致难以诊断的异常。通常,更安全的做法是确保对when
或verify
的调用中的每个参数都是局部变量、常量或文字(可能在Mockito匹配器中,如适用);在这里提取可以更容易地遵守该规则。