当存根ClassOne.methodOne
时,我收到以下关于使用返回值对void方法进行存根的错误消息,即使ClassOne.methodOne
不为空。该错误似乎与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);
为什么会发生这种情况,我该如何解决?
答案 0 :(得分:3)
当您尝试存根Mockito无法覆盖的方法时,可能会发生这种情况。 when
的语法工作方式,Mockito识别它可以检测到的最新调用< / em>作为对stub的方法调用。如果Mockito无法检测到方法调用你是存根,但可以检测到在存根方法的实际实现中发生的模拟调用,那么它可能会将该调用误认为是存根调用。因此,它认为你使用返回值来存在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
,这是模拟上的一个未设置方法。 Mockito的默认实现检测到调用,将调用记录为最后收到的调用,并返回false。然后,在上面的步骤2中,Mockito看到对when
的调用,将最后一次调用标记为存根,并准备调用thenVerb
,这将在步骤3中进行。但是,在这种情况下,在第一步中,Mockito没有覆盖methodOne
,因此它无法检测到呼叫或记录调用。它实际上会调用classOne.methodOne
,如果与模拟有任何交互,则会记录这些内容,就好像它们在when
调用之上的测试中一样。第2步和以前一样,除了Mockito标记了对存根的错误调用,因此第3步看到了thenReturn
对void方法的调用。
如果使用Matchers,这可能会更麻烦,因为如果internal matcher stack上的匹配器数量错误,那么即使测试中的存根调用似乎使用了匹配器,也可能会出现InvalidUseOfMatchersException正确。
当Mockito无法覆盖您正在存根的方法时,会出现此问题。您需要检查以下内容是否正确:
final
,且不应为non-public
parents。static
和非final
。@InjectMocks
创建的,那么它是一个真正的实现,而不是模拟; read more here。doReturn
/doAnswer
/doThrow
syntax时,因为否则你将在调用when
内调用间谍的实际方法。