为了账号安全,请及时绑定邮箱和手机立即绑定

mocktio 验证参数顺序

mocktio 验证参数顺序

回首忆惘然 2021-11-11 16:09:29
我一直在寻找这个一段时间没有答案。假设我有一个使用Calc依赖项的服务类Calc有一个方法除法public void divide(int a,int b)和服务像这样使用它public void serviceAMethod{//do somehtinga=getA();b=getB();calc.divide(a,b);}我的测试看起来像这样@Testpublic void serviceAMethod_callsCalc(){   verify(calcMock).divide(a, b);}这通过了,但是如果我去Calc.divide并将签名更改为public void divide(int b,int a)它仍然通过我如何测试正确的参数是否以正确的顺序传递?编辑:不一定必须与 Mockito 一起使用,我如何使此测试更具弹性?
查看完整描述

3 回答

?
MMMHUHU

TA贡献1834条经验 获得超8个赞

这是因为传递给 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);


查看完整回答
反对 回复 2021-11-11
?
慕丝7291255

TA贡献1859条经验 获得超6个赞

好的,这是我的解决方案,我认为它比完整的集成测试更好


我已将参数重构为 pojo


public 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));

如果您交换操作数,这将失败


查看完整回答
反对 回复 2021-11-11
?
慕容森

TA贡献1853条经验 获得超18个赞

对 serviceAMethod 的测试是在假设签名的情况下编写的,divide即第一个参数是被除数,第二个参数是除数。

现在 的签名divide发生了变化,即第一个参数现在是一个除数,第二个参数是一个被除数。但是测试serviceAMethod还是通过了。

calc 的单元测试肯定会捕捉到这一点,但是如果divide在这种情况下对每个客户端的某些测试也失败了,这会很方便,因为这种签名的更改divide肯定会破坏客户端并需要更改客户端。

当您更改方法解释其参数的方式时,这肯定需要更改方法的客户端。模拟测试divide无法检测到这种变化。

serviceAMethod使用 real的集成测试Calc会检测到这种变化并且会中断。这会给你一个提醒,serviceAMethod应该改变它以其他顺序传递参数。


查看完整回答
反对 回复 2021-11-11
  • 3 回答
  • 0 关注
  • 117 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信