【发布时间】:2019-05-01 21:51:59
【问题描述】:
我正在对我的类进行单元测试并遇到了这种情况:我使用 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()时,问题真的出现了
【问题讨论】:
-
writeObject 是最终的。 Mockito(直到最近的版本,如果你专门配置它)不能模拟最终方法。
-
您实际上是在模拟 Object.class 还是其他特定类型?另外,您知道您使用的是哪个版本的 Mockito/JUnit?
-
@JBNizet 我想就是这样。将在这里检查和评论。当我执行类似的操作时,它通常会显示警告,例如 Mockito.mock(String.class) 但可能是因为我使用的是旧版本的 Mockito (1.10.19)。
-
@JJBrown 是的,实际上是在模拟 Object.class。并使用 1.10.19(这可能是一个问题,正如我对 JB Nizet 的评论......)
-
是的,@JBNizet 是解决方案。如果你想写一个答案,我会接受。
标签: java unit-testing mocking mockito