我是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;
}
在其中一个论坛中,我读到没有通过另一个模拟的构造函数发送模拟,因为Mockito可能会对模拟调用感到困惑,所以我尝试了以下内容:
NumericalValue value = getIntegerValue(2);
child.insertNode(getConstantNode(value));
但无济于事。我确保只调用方法toString()
和getValue()
,因为这些是类具有的唯一方法。我不明白发生了什么。
我也试过单独使用模拟,看看我做错了什么:
child.insertNode(new ConstantNode(getIntegerValue(2)));
完美无缺。
child.insertNode(getConstantNode(new IntegerValue(2)));
这也很好。
答案 0 :(得分:25)
从我在mockito(https://code.google.com/p/mockito/issues/detail?id=53)的“问题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;
}
如果你记得我的代码,参数值也是一个MOCK,那么当value.toString()
上调用thenReturn()
时,我相信(如果我错了,有人请纠正我)触发验证框架并确保每个“when”都有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;
}
这样,可以进行验证。我发现这是一个完整的代码味道,因为我将不得不留下一个注释,解释为什么我在代码中使用看似无用的中间变量。
感谢您的帮助。
答案 1 :(得分:5)
这个问题已经发布了一些很好的修复,但对于仍然无法理解它的人来说,请考虑Java调用所有这些方法的顺序。根据{{3}},Java Java Language Specification:
integerValue.getValue()
,Mockito记录when
,Mockito接听最后一个电话(至integer.getValue
)并开始设置存根value.toString
,这是Mockito记录的模拟电话thenReturn
醇>
Mockito完全是抱怨,因为对模拟的调用,步骤3,在步骤2(when
)之后发生在第4步之前发生<{{1} }),导致验证框架抱怨存根。欢乐,你的答案将麻烦的第3步移到第1步之前,这很好; Sajan完全将其从语句中删除,这也没关系。
答案 2 :(得分:2)
我认为问题在于行
方法Mockito.when(node.toString()).thenReturn(value.toString());
中的 getConstantNode
尝试删除该行并检查其是否有效。 也许你可以做点什么
int num = 2;
child.insertNode(getConstantNode(getIntegerValue(num), num);
...
private ConstantNode getConstantNode(NumericalValue value){
ConstantNode node = Mockito.mock(ConstantNode.class);
Mockito.when(node.evaluate()).thenReturn(value);
Mockito.when(node.toString()).thenReturn(Integer.toString(number));
return node;
}
private IntegerValue getIntegerValue(int number) {
IntegerValue integerValue = Mockito.mock(IntegerValue.class);
Mockito.when(integerValue.getValue()).thenReturn(number);
return integerValue;
}
答案 3 :(得分:0)
我认为这是调用和Mockito Framework验证的排序问题。试试这个,看看它是否有帮助:
...
OperationNode child = getNode(Operation.ADD);
IntegerValue value = getIntegerValue(2);
ConstantNode node = Mockito.mock(ConstantNode.class);
Mockito.when(node.evaluate()).thenReturn(value);
Mockito.when(node.toString()).thenReturn(value.toString());
child.insertNode(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;
}