当前位置: 首页 > 知识库问答 >
问题:

错误:*different*void方法不能使用返回值进行存根

祁建业
2023-03-14

当对classone.methodOne进行stubbing时,我会得到以下关于用返回值对void方法进行stubbing的错误消息,尽管classone.methodOne不是void。该错误似乎与classtwo.methodTwo有关,尽管我正在插入classone.methodOne

org.mockito.exceptions.base.MockitoException: 
`'methodTwo'` is a *void method* and it *cannot* be stubbed with a *return value*!
Voids are usually stubbed with Throwables:
    doThrow(exception).when(mock).someVoidMethod();
***

If you're unsure why you're getting above error read on.
Due to the nature of the syntax above problem might occur because:
1. The method you are trying to stub is *overloaded*. Make sure you are calling
   the right overloaded version.
2. Somewhere in your test you are stubbing *final methods*. Sorry, Mockito does not
   verify/stub final methods.
3. A spy is stubbed using `when(spy.foo()).then()` syntax. It is safer to stub
   spies with `doReturn|Throw()` family of methods. More in javadocs for
   Mockito.spy() method.
public class ClassOne {
  private ClassTwo classTwo;

  public boolean methodOne() {
    classTwo.methodTwo();
    return true;
  }
}

我的测试:

when(classOne.methodOne("some string")).thenReturn(true);

为什么会发生这种情况,我如何修复它?

共有1个答案

艾雪风
2023-03-14

当您试图对Mockito无法重写的方法进行存根处理时,可能会发生这种情况。与时的语法一样,Mockito将它可以检测到的最近调用标识为对stub的方法调用。如果Mockito不能检测到您要进行stubbing的方法调用,但可以检测到在stubbed方法的实际实现中发生的对mock的调用,那么它可能会将该调用误认为是stubbing调用。因此,它认为您正在用返回值替换void方法classtwo.methodTwo,并抛出异常。

/* 1 */  when(classOne.methodOne("some string")).thenReturn(true);
/* 2 */  when(              false              ).thenReturn(true);
/* 3 */  (    internal mockito stub object     ).thenReturn(true);

通常,Mockito调用classone.methodOne,这是mock上的一个非stubbed方法。Mockito的默认实现检测调用,将调用记录为最后一次接收的调用,并返回false。然后,在上面的步骤2中,Mockito在时查看对的调用,将最后一次调用标记为存根,并准备对thenverb的调用,这将出现在步骤3中。但是,在本例中,在第一步中,Mockito没有重写methodOne,因此它无法检测调用或记录调用。它实际上调用classone.methodOne,如果有任何与mock的交互,这些交互将被记录,就像它们在When调用的测试中一样。除了Mockito标记了错误的存根调用外,第2步继续进行,因此第3步将看到对void方法的thenreturn的调用。

如果使用匹配器,这可能会更麻烦,因为如果内部匹配器堆栈上的匹配器数量错误,那么即使测试中的stubbing调用似乎正确使用了匹配器,您也可能会得到一个InvalidUseOfMatchersException。

当Mockito不能重写您要处理的方法时,就会出现这个问题。您需要检查以下内容是否正确:

  • 类应该是非final,并且不应该有非public父级。
  • 方法应该是非静态和非最终
  • 实例应该是Mockito模拟。请注意,如果它是用@injectmocks创建的,那么它是一个真正的实现,而不是模拟;在这里阅读更多信息。
  • 如异常中所述,在拦截间谍时,使用doReturn/doAnswer/doThrow语法,否则将在调用when
  • 时调用间谍的实际方法。

 类似资料:
  • 我相信这是一个愚蠢的问题,但我已经讨论了很久了。。我试图创建一个java程序,根据用户输入的年数和金额计算复利。但我一直遇到一个错误,void方法无法返回值。因此,我将方法切换为double,因为这是将返回的内容,但它告诉我double方法必须返回double。即使我在循环中返回一个双倍。。。请帮忙

  • 我有以下问题:有一个计算两个整数之间相似性的布尔静态方法,我被要求返回4个结果: 在不更改方法的返回类型的情况下,它应该保持布尔值。 不更新/使用外部变量和对象的值

  • 我有一个验证方法,将两个输入作为开始日期和结束日期,并检查结束日期是否有效,即在开始日期之后。我使用Calendar方法获取两个日期的毫秒数并得到差值。如果差值为负值,则其无效的结束日期,即结束日期早于开始日期。结束日期的毫秒值应始终大于开始日期。但在某些情况下,在开始日期的情况下,getTimeInMillis()会提供更大的值。 这是我的代码: 输出为: 这里2015-01-31是开始日期,2

  • 问题内容: 我认为以下代码应该可以工作,但是不能 (编辑:现在可以在PHP 5.5+中工作) : 简单地在哪里: 但是我最终遇到了这个错误: 在写上下文中不能使用方法返回值 这是什么意思?这不只是阅读吗? 问题答案: 需要通过引用访问该值(以检查该引用是否指向存在的对象),并且5.5之前的PHP不支持对从函数返回的临时值的引用。 但是,您真正的问题是,您根本使用了所有内容,错误地认为“空”值与“假

  • 问题内容: 在哪里返回。这不会编译…我 几乎 可以理解为什么。但是,如果我想从一个空白中返回一个空白,为什么不呢?相反,我最终写了这样的东西: 我不是在寻找代码样式建议,我想知道为什么Java明确禁止这种类型的void返回。任何信息表示赞赏,谢谢。 问题答案: 带有表达式的return语句返回该表达式的值。的类型的是空隙表达-它不 具有 一个值。 从逻辑上讲,您想执行,然后返回-所以您必须说。这两

  • 我是JS的学生。我有一段代码返回了一个错误。 这是返回的语法错误。你们能解释一下我做错了什么吗?