我正在对我的类进行单元测试,并遇到了这种情况:我使用Mockito模拟对象并在该对象上调用方法。当我这样做时,我希望不调用真正的方法,并且程序流程将继续。发生的是正在调用实际方法,并且我收到了NullPointerException,因为如果我使用此参数调用该方法,将会发生这种情况。
Mockito.mock不能阻止此行为吗?
Mockito documentation说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, ...).
,this answer证实了我对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()
答案 0 :(得分:0)
Mockito不会改变语言的工作方式。方法按照它们在代码中的排列顺序调用。 这意味着在像这样的模拟方法的情况下:
when(mockObject.getSomething()).thenReturn(SOMETHING_ELSE);
首先在模拟对象上调用getSomething()
,然后在控制要测试的代码之前,mockito的基础结构替换返回值。
这意味着,如果getSomething()
调用了模拟对象的某些依赖项,则后者不会被初始化并生成NPE。
解决方法是使用配置模拟的另一种形式:
doReturn(SOMETHING_ELSE).when(mockObject ) .getSomething();
请不要将when
的右括号从方法的后面移到.
的前面。
这使Mokito可以拦截完整的方法调用,从而不会引发NPE。
答案 1 :(得分:0)
JBNizet正确回答了问题评论。
writeObject是最终的。 Mockito(直到最新版本为止,如果您专门配置为这样做)则无法模拟最终方法。