我是Mockito的新手,我试过调查这个例外但我还没有找到具体的答案.当我一起使用两个模拟时,它发生在我的代码中,这意味着我通过模拟的构造函数,另一个模拟.像这样:
...
OperationNode child = getNode(Operation.ADD);
child.insertNode(getConstantNode(getIntegerValue(2));
...
private ConstantNode getConstantNode(NumericalValue value){
ConstantNode node = Mockito.mock(ConstantNode.class);
Mockito.when(node.evaluate()).thenReturn(value);
Mockito.when(node.toString()).thenReturn(value.toString());
return node;
}
private IntegerValue getIntegerValue(int number) {
IntegerValue integerValue = Mockito.mock(IntegerValue.class);
Mockito.when(integerValue.getValue()).thenReturn(number);
Mockito.when(integerValue.toString()).thenReturn(Integer.toString(number));
return integerValue;
}
Run Code Online (Sandbox Code Playgroud)
在其中一个论坛中,我读到没有通过另一个模拟的构造函数发送模拟,因为Mockito可能会对模拟调用感到困惑,所以我尝试了以下内容:
NumericalValue value = getIntegerValue(2);
child.insertNode(getConstantNode(value));
Run Code Online (Sandbox Code Playgroud)
但无济于事.我要确保,只有方法toString()和getValue()被调用,因为只有这些方法的类了.我不明白发生了什么.
我也试过分别使用模拟,看看我做错了什么:
child.insertNode(new ConstantNode(getIntegerValue(2)));
Run Code Online (Sandbox Code Playgroud)
这非常有效.
child.insertNode(getConstantNode(new IntegerValue(2)));
Run Code Online (Sandbox Code Playgroud)
这也很好.
Cha*_*mor 27
根据我在mockito的"问题53"上的内容(https://code.google.com/p/mockito/issues/detail?id=53),由于Mockito中涉及的验证框架,我的代码遇到了问题.确切地说,下面的代码本身导致了异常.
private ConstantNode getConstantNode(NumericalValue value){
ConstantNode node = Mockito.mock(ConstantNode.class);
Mockito.when(node.evaluate()).thenReturn(value);
Mockito.when(node.toString()).thenReturn(value.toString());
return node;
}
Run Code Online (Sandbox Code Playgroud)
如果你记得我的代码,参数值也是一个MOCK,所以当value.toString()调用时thenReturn(),我相信(有人请纠正我,如果我错了)验证框架被触发并确保每个"何时"有它的thenReturn()被调用/验证/等.因此,如果发生这种情况, Mockito.when(node.toString()).thenReturn(value.toString() 将不会验证,因为它没有从中返回valute.toString(),这启动了整个"验证一切"链.
我是如何修理它的:
private ConstantNode getConstantNode(NumericalValue value){
ConstantNode node = Mockito.mock(ConstantNode.class);
Mockito.when(node.evaluate()).thenReturn(value);
String numberToString = value.toString();
Mockito.when(node.toString()).thenReturn(numberToString);
return node;
}
Run Code Online (Sandbox Code Playgroud)
这样,它就可以被验证.我发现这是一个完整的代码味道,因为我将不得不留下一个注释,解释为什么我在代码中使用看似无用的中间变量.
谢谢您的帮助.
已经在这个问题中发布了一些很好的修复,但对于仍然无法理解它的人,请考虑Java调用所有这些方法的顺序.根据Java语言规范,Java 在调用方法之前从左到右评估方法的每个参数:
integerValue.getValue(),Mockito记录when,Mockito接到最后一个电话(to integer.getValue)并开始设置存根value.toString,这是Mockito记录的模拟电话thenReturn 在stubber上Mockito完全抱怨,因为对模拟的调用,步骤3,发生在步骤2(when)之后但是在步骤4(thenReturn)之前,导致验证框架抱怨存根.欢乐,你的答案将麻烦的第3步移到第1步之前,这很好; Sajan完全将它从语句中删除,这也没关系.