使用 Mockito thenCallRealMethod 时出现 NullPointerException

Ert*_*i87 5 java unit-testing mockito

我有一个关于使用 Mockito thenCallRealMethod 的问题。我已阅读有关使用此功能的警告;基本上,我想将其写入我的测试中,以确保我的应用程序逻辑不会过时,因为它被用作库,并且我想确保我的库的用户拥有面向未来的保护。

我的测试用例如下所示:

@Test
public void Test() {
    when(restTemplate.postForEntity(...)).thenReturn(new ResponseEntity<>(realObjectMapper.writeValueAsString(data), HttpStatus.OK));
    when(objectMapper.readValue(realObjectMapper.writeValueAsString(data), TestData.class)).thenCallRealMethod();
    TestData result = tested.callMethod(...);
    ....
}
Run Code Online (Sandbox Code Playgroud)

TestData 是一个简单的 POJO,其中包含一堆字段,但没有什么特别有趣的,而 data 是 TestData 的一个实例。objectMapper 是FasterXML Jackson ObjectMapper的模拟实例,而 realObjectMapper 是同一类的真实(未模拟)实例。

当我的应用程序尝试按照测试第二行的 thenCallRealMethod 执行 objectMapper.readValue (在模拟实例上)时,我遇到的问题是 NullPointerException 。我已经验证,当我将相同的输入传递给 realObjectMapper.readValue 时,它​​执行得很好,因此输入没有任何问题。我缺少什么?

Stack trace:
java.lang.NullPointerException
    at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2842)
    .... (my code here)
Run Code Online (Sandbox Code Playgroud)

dha*_*eme 2

当您使用模拟对象时,真实对象不会被初始化。这意味着即使具有默认值的任何属性也将为 null。

就我而言,我有一个从属性文件中注入 @Value 的属性,但如果我定义一个默认值,它会发生同样的情况,当它要被使用时它是 null 。

解决方案:必须检查哪个属性导致方法上出现空指针异常,然后模拟一个返回该属性的预期值的 getter 并从实际方法中调用该 getter,或者使用测试中的 setter 设置其值,创建模拟对象后