我已经搜索了一段时间,没有答案。
让我说我有一个类 Service ,它使用 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,如何使此测试更具弹性?
答案 0 :(得分:2)
这是因为传递给Calc.divide的值仍然相同。 Mockito验证传递的值而不是参数的名称。因此,除非您更改在serviceAMethod方法中所做的调用以反映更改,否则更改Calc类中参数的顺序不会影响测试。
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);
答案 1 :(得分:0)
在对serviceAMethod进行测试的情况下,假设divide
的签名即第一个参数为除数,第二个参数为除数。
现在divide
的签名已更改,即第一个参数现在是除数,第二个参数是除数。但是serviceAMethod
的测试仍然通过。
用于calc的单元测试肯定会捕获到这一点,但是如果divide
的每个客户端的某些测试在这种情况下也失败,则很方便,因为divide
的签名更改肯定会破坏客户端,并且要求更改客户。
当您更改方法解释其参数的方式时,肯定需要更改该方法的客户端。测试模拟divide
无法检测到这种变化。
使用真实的serviceAMethod
的{{1}}的集成测试将检测到这种变化并将中断。这会提醒您Calc
应该更改,以便它以其他顺序传递参数。
答案 2 :(得分:0)
好的,这是我的解决方案,我认为它比全面的集成测试要好
我将参数重构为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));
如果您交换操作数,此操作现在将失败