当我试图模拟ObjectInputStream对象时,我会得到一个NullPointerException。更准确地说,当这一行被调用时:when(inputStream.readObject()).thenReturn(new Person("Doe", "John", "123"));
代码片段:
@RunWith(MockitoJUnitRunner.class)
public class ConnectionTest{
...
@Mock
private ObjectInputStream inputStream;
...
@Test
public void test(){
...
when(inputStream.readObject()).thenReturn(new Person("Doe", "John", "123"));
...
}
}通常,在初始化ObjectInputStream时,必须传递一个InputStream对象作为构造函数参数,我敢打赌这就是问题所在--没有分配给ObjectInputStream的InputStream。
那么,我应该如何正确地模拟ObjectInputStream呢?
发布于 2017-07-10 14:02:38
这是由于readObject()是最终这一事实造成的。
Mockito不能模拟最终的方法。所以,试图指定对模拟对象的调用.只是出了点问题。是的,NPE被抛出的事实不仅仅是误导。
您可以尝试在Mockito 2中使用允许模拟最终方法的https://static.javadoc.io/org.mockito/mockito-core/2.8.47/org/mockito/Mockito.html#39特性。如果这不适用于您,PowerMock(ito)或JMockit最有可能完成这项工作。
这只是为了记录:这些微妙的问题是不再使用Java内置序列化的另一个很好的理由。
绕过这一点的唯一其他方法是:针对相应的接口 ObjectInput编程,而不是特定的实现类。
因为您可以轻松地模拟这个接口。
但当然,这意味着更改您的生产代码。这可能不是个坏主意,因为将业务逻辑与实际的序列化形式分离开来。如果以后选择序列化为JSON字符串,则只需使用GSON -替换该接口的实现即可。
发布于 2017-07-10 14:02:24
您不能模拟final方法,因为它不是可重写的,而且readObject()是final:
public final Object readObject(){...}要实现目标,可以重构实际代码。
例如,您可以引入一个包装类,该类包含ObjectInputStream实例,并将处理委托给它。
通过这种方式,可以模拟这个包装类的readObject()方法。
您也可以使用提供比Mockito更多功能的Powermock,但我真诚地避免使用它。
https://stackoverflow.com/questions/45013934
复制相似问题