Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Mockito未完成存根异常_Java_Mockito - Fatal编程技术网

Java Mockito未完成存根异常

Java Mockito未完成存根异常,java,mockito,Java,Mockito,我是Mockito的新手,我尝试过调查这个例外,但我还没有找到具体的答案。它发生在我的代码中,当我同时使用两个mock时,这意味着我通过一个mock的构造函数给出另一个mock。像这样: ... OperationNode child = getNode(Operation.ADD); child.insertNode(getConstantNode(getIntegerValue(2)); ... private ConstantNode getConstantNode(Numerical

我是Mockito的新手,我尝试过调查这个例外,但我还没有找到具体的答案。它发生在我的代码中,当我同时使用两个mock时,这意味着我通过一个mock的构造函数给出另一个mock。像这样:

...
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
    可点击链接:模拟返回模拟通常是一个代码气味,“号码”在哪里从那时起?它解决了异常问题,但我仍然不理解为什么会发生这种情况。我阅读了第一条评论中的问题链接,但我仍然不理解。这不是同样的事情吗,只是没有一个方法?…同样,我试过了,没有用。谢谢!最后我开始理解这一点研发问题。