我正在单位测试我的课程并遇到这种情况:我使用摩agito嘲笑一个对象,并在该对象上调用方法。当我这样做时,我希望不调用真正的方法,并且程序流将继续。发生的事情是,真正的方法正在调用,我得到了一个NullpoInterException,因为如果我用此参数调用该方法,那将会发生。
Mockito.Mock不应该防止此行为吗?
Mockito文档说By default, for all methods that return value, mock returns null, an empty collection or appropriate primitive/primitive wrapper value (e.g: 0, false, ... for int/Integer, boolean/Boolean, ...).
,此答案确认了我的In a mock all methods are stubbed and return "smart return types". This means that calling any method on a mocked class will do nothing unless you specify behaviour.
代码:
public class BrokenTest {
@Test
public void shouldPassBecauseItIsMocked() throws IOException {
Object anyObject = Mockito.mock(Object.class);
ObjectOutputStream objectOutputStream = Mockito.mock(ObjectOutputStream.class);
objectOutputStream.writeObject(anyObject);
}
}
我希望这项测试能够通过,但是我会得到一个NullpoInterException:
java.lang.NullPointerException
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1108)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:348)
at packageName.BrokenTest.shouldPassBecauseItIsMocked(BrokenTest.java:14)
...
(BrokenTest.java:14
实际上是objectOutputStream.writeObject(anyObject);
行(
P.S。:我并不是真正试图测试ObjectOutputStream
,而是使用ObjectOutputStream.writeObject(Object object)
的一类。当我做myObjectWithMockedObjectOutputStream.methodThatCallsWriteObject()
Mockito不会像语言的运作方式那样chenge。这些方法按照代码中的顺序调用。在这样的模拟方法的情况下,这意味着:
when(mockObject.getSomething()).thenReturn(SOMETHING_ELSE);
在模拟对象上调用了第一个getSomething()
,然后在对您的测试中的代码控制之前,Mockito的基础结构替换了返回值。
这意味着,如果getSomething()
调用模拟对象的某些依赖项,则未初始化并导致NPE。
解决此问题的工作是使用其他形式的配置模拟:
doReturn(SOMETHING_ELSE).when(mockObject ) .getSomething();
请不要说when
的闭合支架从方法后面移动到.
之前。
这允许Mokito拦截完整的方法调用,以免投掷NPE。
jbnizet在问题评论上正确回答。
写入对象是最终的。Mockito(直到最近的版本,如果您专门为此进行了配置(无法模拟最终方法。