【问题标题】:Mockito and PowerMock for ObjectInputStreamObjectInputStream 的 Mockito 和 PowerMock
【发布时间】:2021-04-22 02:15:26
【问题描述】:

我正在尝试测试一种使用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 的任何想法?

【问题讨论】:

  • 你不必嘲笑一切。将ByteArrayOutputStream 传递给您的测试方法,然后检查其内容。
  • @chrylis-cautiouslyoptimistic- 关键是我不改变方法。由于该方法在其主体中实例化了一个新的 InputStream,因此我需要模拟构造函数。
  • 但是ObjectInputStream 包装另一个底层输入流。
  • 我真的不需要模拟ObjectInputStream 对象,我只需要使用PowerMock 来确保每次调用new ObjectInputStream() 时,都会调用一个特定的ObjectInputStream(可能是我预定义的) ) 被退回。这可能吗?
  • 我非常怀疑您的代码是否调用了new ObjectInputStream()。请提供相关部分。

标签: java mocking mockito powermockito


【解决方案1】:
@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   
    }

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

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

【讨论】:

    【解决方案2】:

    您的陈述“这个要测试的方法在每次调用它时都会实例化一个新的 ObjectInputStream”意味着您可以提高它的可测试性。对具体类进行编码的缺点是您有隐藏的依赖项,需要借助非标准技术进行测试。

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

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

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

    如果您选择选项 2。您的测试可能如下所示:

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

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

    【讨论】:

      猜你喜欢
      • 2019-05-31
      • 1970-01-01
      • 2017-04-20
      • 1970-01-01
      • 1970-01-01
      • 2011-08-27
      • 1970-01-01
      • 2018-11-29
      • 1970-01-01
      相关资源
      最近更新 更多