ObjectInputStream 的 Mockito 和 PowerMock

Mockito and PowerMock for ObjectInputStream

我正在尝试测试一种使用 ObjectInputStream 从文件中读取数据的方法,但我想对 ObjectInputStream 使用模拟。这个要测试的方法每次调用都会实例化一个新的ObjectInputStream,所以我需要使用PowerMock来模拟构造函数,这样每次实例化一个ObjectInputStream时,它都是一个模拟。这是我目前所拥有的:

@Test
public void test() throws Exception {
    ObjectInputStream inputStream = mock(ObjectInputStream.class);
    when(inputStream.readObject()).thenReturn(object);
    PowerMockito.whenNew(ObjectInputStream.class).withAnyArguments().thenReturn(inputStream);
    myFun() // call method to be tested   
}

但是,由于某些原因这不起作用,因为我在 when(inputStream.readObject()) 处收到 NullPointerException,我不知道为什么。关于如何模拟 ObjectInputStream 的任何想法?

@Test
    public void test() throws Exception {
        Object object = mock(Object.class);
        ObjectInputStream inputStream = mock(ObjectInputStream.class);
        when(inputStream.readObject()).thenReturn(object);
        PowerMockito.whenNew(ObjectInputStream.class).withAnyArguments().thenReturn(inputStream);
        myFun() // call method to be tested   
    }

您是否在其他地方创建了对象?

你的测试应该断言某些东西?

您的陈述“每次调用此要测试的方法时都会实例化一个新的 ObjectInputStream”暗示您可以提高其可测试性。编码到具体的缺点 class 是你有一个隐藏的依赖,需要求助于非标准技术进行测试。

我的建议是看看你是否可以公开依赖项。有几种方法可以做到这一点。

  1. 将您的 ObjectInputStream 传递到函数中,而不是创建您自己的函数。
  2. 向 class 添加一个 Function<ObjectInputStream,FileInputStream> 字段,这样您就可以模拟新实例而无需求助于 PowerMock。

还要考虑是否可以编码到 ObjectInput 接口而不是具体的 class。

如果您选择选项 2,那么您的测试可能类似于:

ObjectInput mockObjectInput = mock(ObjectInput.class);
when(mockObjectInput.readObject()).thenReturn(object);    
ClassUnderTest testInstance = new ClassUnderTest(fis -> mockObjectInput);
testInstance.methodUnderTest();
verify...

在我看来,这将使您的测试更具可读性,并且依赖性更加明确。