在junit测试中使用mock和fake对象

时间:2016-04-16 05:31:02

标签: java unit-testing mocking mockito

在单元测试代码中同时使用模拟对象和伪对象是否正常。

实施例

when(computationHelper.someMethod()).thenReturn(stringGrid.writeCell(rowNum,colNum,value));

其中calculateHelper是mock对象,stringGrid是我自己的实现和伪对象。

1 个答案:

答案 0 :(得分:0)

是的,绝对允许在同一测试中使用各种test doubles,包括模拟,假货和存根。正如评论中提到的ndrone一样,您可能希望选择一个命名系统或约定来帮助您确定哪些依赖项是模拟或伪造的,特别是为了更容易帮助您诊断测试是否因为缺少模拟期望或由于实际系统故障。

你也可以考虑使用真正的实现;毕竟,决定隔离你的被测单元可能会过度,因为人们希望你可以信任JRE的实现或Mockito的实现,你不应该试图嘲笑或替换那些。我倾向于使用真正的实现,当它们快速,确定性和经过良好测试时 - 并且当它们足够简单而不需要自己的深度依赖图时。 (这需要一些判断;例如,我很想使用真正的EmailAddressParser,但可能不是真正的FullStackRpcServer。)

但需要注意的一点是:您可能希望将返回值提取到变量。

Result result = stringGrid.writeCell(rowNum,colNum,value);
when(computationHelper.someMethod()).thenReturn(someMethodResult);

这有两个原因:

  1. 对于Mockito的新手,您的原始语法可能看起来每次调用writeCell时都会调用someMethod,实际上除非您编写自己的答案,否则不会发生这种情况。将其提取到变量可以清楚地表明,当您设置writeCell语句时,Mockito将仅对when进行一次评估。

  2. 虽然在使用虚假或真实实现时您的语法正常,但如果stringGrid是模拟,则类似的代码可能无效。这是因为Mockito relies heavily on side-effects and execution order,因此在存根方法中调用模拟可能会导致难以诊断的异常。通常,确保调用whenverify中的每个参数都是局部变量,常量或文字(可能在Mockito匹配器中,如果适用)更安全;在这里提取可以更容易地遵守该规则。