存根时ClassOne.methodOne
,我收到以下有关错误消息的方法错误消息:即使返回的值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);
为什么会发生这种情况,我该如何解决?
当您尝试对Mockito无法覆盖的方法进行存根时,可能会发生这种情况。when
Mockito的语法工作方式将它可以检测到的最新调用识别为对存根的方法调用。如果Mockito无法检测到您正在存根的方法调用,但是可以检测到在存根方法的实际实现中发生的对模拟的调用,则可能将该调用误认为存根调用。因此,它认为您正在ClassTwo.methodTwo
使用返回值对void方法进行存根,并引发异常。
/* 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,这甚至会更加麻烦,因为如果内部Matcher堆栈上的Matchers数量错误,那么即使测试中的存根调用似乎正确使用了Matchers,也可能会收到InvalidUseOfMatchersException。
当Mockito无法覆盖您正在存根的方法时,就会出现此问题。您需要检查以下各项是否正确:
final
,并且不应有非public
父母。static
和非final
。@InjectMocks
,它是一个真实的实现,而不是模拟;在这里阅读更多。doReturn
/ doAnswer
/doThrow
语法,因为否则你将调用间谍的实际方法从调用内when
。本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句