Java Mockito未完成存根异常
我是Mockito的新手,我尝试过调查这个例外,但我还没有找到具体的答案。它发生在我的代码中,当我同时使用两个mock时,这意味着我通过一个mock的构造函数给出另一个mock。像这样:Java Mockito未完成存根异常,java,mockito,Java,Mockito,我是Mockito的新手,我尝试过调查这个例外,但我还没有找到具体的答案。它发生在我的代码中,当我同时使用两个mock时,这意味着我通过一个mock的构造函数给出另一个mock。像这样: ... OperationNode child = getNode(Operation.ADD); child.insertNode(getConstantNode(getIntegerValue(2)); ... private ConstantNode getConstantNode(Numerical
...
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;
}
在其中一个论坛中,我读到关于不通过另一个mock的构造函数发送mock,因为Mockito可能会与mock调用混淆,所以我尝试了以下方法:
NumericalValue value = getIntegerValue(2);
child.insertNode(getConstantNode(value));
但是没有用。我确保只调用方法toString()
和getValue()
,因为这些是类仅有的方法。我不明白发生了什么事
我还尝试单独使用模拟,看看我是否做错了什么:
child.insertNode(new ConstantNode(getIntegerValue(2)));
那很好用
child.insertNode(getConstantNode(new IntegerValue(2)));
这也很好。我认为这是调用顺序和Mockito框架验证的问题。试试这个,看看是否有帮助:
...
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;
}
来源:我认为问题出在线路上
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;
}
从我在mockito()的“问题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,因此当在thenReturn()
上调用value.toString()
时,我相信(如果我错了,请有人纠正我)会触发验证框架,并确保每个“when”都有它的thenReturn()
调用/validated/etc。因此,如果发生这种情况,Mockito.when(node.toString()).thenReturn(value.toString()
将不会被验证,因为它没有从启动整个“验证一切”链的valuate.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;
}
通过这种方式,它可以被验证。我发现这是一个完整的代码味道,因为我必须留下一条注释,解释为什么我在代码中使用了一个看起来毫无用处的中间变量
感谢您的帮助。在这个问题中已经发布了一些很好的修复方法,但是对于理解它仍然有困难的人,请想想Java调用所有这些方法的顺序。根据,Java:
integerValue.getValue()
,由Mockito记录
when
,其中Mockito接受最后一次调用(调用integer.getValue
)并开始设置存根
value.toString
,这是Mockito记录的模拟调用
然后在存根上返回
Mockito之所以抱怨,正是因为对mock的调用,即步骤3,发生在步骤2之后(when
),但发生在步骤4之前(thenReturn
),导致验证框架抱怨存根。Joy,您的答案将麻烦的步骤3移到步骤1之前,这很好;Sajan将其从语句中完全删除,这也很好。已知问题https://code.google.com/p/mockito/issues/detail?id=53
可点击链接:模拟返回模拟通常是一个代码气味,“号码”在哪里从那时起?它解决了异常问题,但我仍然不理解为什么会发生这种情况。我阅读了第一条评论中的问题链接,但我仍然不理解。这不是同样的事情吗,只是没有一个方法?…同样,我试过了,没有用。谢谢!最后我开始理解这一点研发问题。