Mockito UnfinishedStubbingException

我是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))); 

这也很好。

根据我在mockito的“问题53”上的内容( https://code.google.com/p/mockito/issues/detail?id=53 ),由于Mockito中涉及的validation框架,我的代码遇到了问题。 确切地说,下面的代码本身导致了exception。

 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() ,我相信(如果我错了,有人请纠正我)validation框架被触发并确保每个“when”都有thenReturn()调用/ validated / thenReturn() 因此,如果发生这种情况, Mockito.when(node.toString()).thenReturn(value.toString() 将不会被validation,因为它没有valute.toString()返回,这启动了整个“validation一切“链。

我是如何修理它的:

 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; } 

这样,它就可以被validation。 我发现这是一个完整的代码味道,因为我将不得不留下一个注释,解释为什么我在代码中使用看似无用的中间变量。

谢谢您的帮助。

已经在这个问题中发布了一些很好的修复,但对于仍然无法理解它的人,请考虑Java调用所有这些方法的顺序。 根据Java语言规范 ,Java 在调用方法之前从左到右评估方法的每个参数 :

  1. integerValue.getValue() ,Mockito记录
  2. when ,Mockito接受最后一次调用(到integer.getValue )并开始设置存根
  3. value.toString ,这是Mockito记录的模拟调用
  4. thenReturn

Mockito完全抱怨,因为对模拟的调用,步骤3,发生步骤2( 之后 )之后但是步骤4之后( thenReturn ),导致validation框架抱怨存根。 欢乐,你的答案将麻烦的第3步移到第1步之前,这很好; Sajan完全将其从语句中删除,这也没关系。

我认为这个问题与线路有关

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 Frameworkvalidation的排序问题。 试试这个,看看它是否有帮助:

 ... 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; } 

资料来源: https : //code.google.com/p/mockito/issues/detail?id = 53