Java 在junit测试中同时使用模拟对象和伪对象

Java 在junit测试中同时使用模拟对象和伪对象,java,unit-testing,mocking,mockito,Java,Unit Testing,Mocking,Mockito,在单元测试代码中同时使用模拟对象和伪对象可以吗 范例 when(computationHelper.someMethod()).thenReturn(stringGrid.writeCell(rowNum,colNum,value)); computationHelper是模拟对象,stringGrid是我自己的实现,是一个伪对象。是的,绝对允许在同一个测试中使用各种方法,包括模拟、伪造和存根。如注释中所述,您可能希望选择一个命名系统或约定来帮助您确定哪些依赖项是模拟的还是伪造的,尤其是为了更

在单元测试代码中同时使用模拟对象和伪对象可以吗

范例

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

computationHelper是模拟对象,stringGrid是我自己的实现,是一个伪对象。

是的,绝对允许在同一个测试中使用各种方法,包括模拟、伪造和存根。如注释中所述,您可能希望选择一个命名系统或约定来帮助您确定哪些依赖项是模拟的还是伪造的,尤其是为了更容易帮助诊断测试是否由于缺少模拟预期或由于实际的系统故障而失败

您也可以考虑使用实际实现;毕竟,隔离测试中的单元的决定可能会做得太过分,因为人们希望您能够信任JRE的实现或Mockito的实现,而您不应该试图模仿或替换这些实现。我倾向于使用真正的实现,当它们是快速的、确定性的、经过良好测试的,并且它们足够简单,不需要深度依赖图本身时。(这需要一点判断;例如,我很想使用真正的EmailAddressParser,但可能不是真正的FullStackRpcServer。)


不过有一点需要注意:您可能希望提取变量的返回值

Result result = stringGrid.writeCell(rowNum,colNum,value);
when(computationHelper.someMethod()).thenReturn(someMethodResult);
这有两个原因:

  • 对于Mockito的新手来说,每次调用
    someMethod
    时都会调用
    writeCell
    ,实际上除非您自己编写答案,否则不会发生这种情况。将其提取到一个变量可以清楚地表明,在设置
    when
    语句时,Mockito将只计算
    writeCell
    一次

  • 虽然在使用伪实现或真实实现时语法可以正常工作,但如果
    stringGrid
    是模拟的,则类似的代码可能无法工作。这是因为,在一个方法中调用一个模拟的方法可能会导致难以诊断的异常。通常,更安全的做法是确保调用
    验证
    中的每个参数都是局部变量、常量或文字(可能在Mockito匹配器中,如适用);在这里提取使遵守该规则变得更容易


  • 这很好,但模拟的整个思想是将组件从类依赖链中隔离出来,因此将假对象与之耦合似乎是不对的,没有任何规则禁止它。我会确保我的模拟对象在变量名中有
    mock