猿问

mocktio 验证参数顺序

我一直在寻找这个一段时间没有答案。


假设我有一个使用Calc依赖项的服务类


Calc有一个方法除法


public void divide(int a,int b)

和服务像这样使用它


public void serviceAMethod{

//do somehting

a=getA();

b=getB();

calc.divide(a,b);

}

我的测试看起来像这样


@Test

public void serviceAMethod_callsCalc(){

   verify(calcMock).divide(a, b);

}

这通过了,但是如果我去Calc.divide并将签名更改为


public void divide(int b,int a)

它仍然通过


我如何测试正确的参数是否以正确的顺序传递?


编辑:不一定必须与 Mockito 一起使用,我如何使此测试更具弹性?


回首忆惘然
浏览 150回答 3
3回答

MMMHUHU

这是因为传递给 Calc.divide 的值仍然相同。Mockito 验证传递的值而不是参数的名称。因此更改 Calc 类中参数的顺序不会影响测试,除非您更改方法 serviceAMethod 中完成的调用以反映更改。public void serviceAMethod() {  //do somehting  a=getA();  b=getB();  calc.divide(b,a);}只有在您更改此逻辑(这是您正在测试的)之后,您的测试才会失败。如果您使用实际值,您可以看到这一点:public void serviceAMethod() {   a=getA(); // EG: 1    b=getB(); // EG: 2   calc.divide(1, 2); // effective call}如果您在 Calc 类中交换 a 和 b,它仍将使用值 1、2 调用。然后您测试以下内容:verify(calcMock).divide(1, 2);

慕丝7291255

好的,这是我的解决方案,我认为它比完整的集成测试更好我已将参数重构为 pojopublic class OperationRequest {    private int firstOperand;    private int secondOperand;    //equals and hashCode, important!}然后 Calc.divide 变成calc.divide(OperationRequest request);和断言verify(calcMock).divide(new OperationRequest(1,2));如果您交换操作数,这将失败

慕容森

对 serviceAMethod 的测试是在假设签名的情况下编写的,divide即第一个参数是被除数,第二个参数是除数。现在 的签名divide发生了变化,即第一个参数现在是一个除数,第二个参数是一个被除数。但是测试serviceAMethod还是通过了。calc 的单元测试肯定会捕捉到这一点,但是如果divide在这种情况下对每个客户端的某些测试也失败了,这会很方便,因为这种签名的更改divide肯定会破坏客户端并需要更改客户端。当您更改方法解释其参数的方式时,这肯定需要更改方法的客户端。模拟测试divide无法检测到这种变化。serviceAMethod使用 real的集成测试Calc会检测到这种变化并且会中断。这会给你一个提醒,serviceAMethod应该改变它以其他顺序传递参数。
随时随地看视频慕课网APP

相关分类

Java
我要回答