在循环中使用 Mockito argThat 会导致 NullPointerException

问题描述 投票:0回答:1

其中一项遗留测试使用 Mockito

argThat
在循环中存根相应的结果。

如果我将迭代次数减少到 1,它就会通过(

numberOfItems = 1
,即如果没有循环)。

一旦进入第二次迭代,就会出现 NPE 错误:

java.lang.NullPointerException: Cannot invoke "getValue()" because "arg" is null

代码是这样的:

 @Test
 public void testMy() {
     int numberOfItems = 2;
     List<MyData> myDataList = getTestData(numberOfItems);
     
     for (MyData md : myDataList) {
         when(mockedService.someMethod(
                argThat(arg -> Objects.equals(arg.getValue(), md.getMyValue())))) // NPE here on arg.getValue()
             .thenReturn(getExpectedResult(md.getMyValue()));
     }
     
     List<MyData> resData = testService.methodUnderTest(myDataList);
     
     // assert... resData list has all the expected items and values
 }

正在测试的方法类似如下

public List<MyData> methodUnderTest(List<MyData> myDataList) {
    myDataList.forEach(myData -> {
            // ... some logic ...
        
            myData.setResult(mockedService.someMethod(new MyRequest(myData.getMyValue())));
        }
    });

    return myDataList;
}

但是对于错误情况,甚至没有达到方法调用,因为 NPE 发生在单元测试代码的较早位置。

最初它是这样使用的

when(mockedService.someMethod(
       argThat(hasProperty("value", equalTo(md.getMyValue())))))
    .thenReturn(getExpectedResult(md.getMyValue()));

但是,我看到建议更喜欢直接比较对象,所以我尝试按照建议重新编写存根,摆脱那些

equalTo
hasProperty
,机器人现在陷入了那些 NPE 错误:)

请问我做错了什么有什么建议吗?谢谢!!

java mockito matcher
1个回答
0
投票

在循环中使用 Mockito 的 argThat 时,您似乎遇到了 NullPointerException。此问题可能与对象的状态或循环中处理它们的方式有关。在没有看到实际代码的情况下,我可以提供一些一般性建议来帮助您排除故障:

检查空对象: 确保您尝试在循环内交互的对象不为空。您遇到的错误(无法调用“getValue()”,因为“arg”为空)表明引用为 arg 的对象为空。

验证循环实现: 仔细检查您的循环实现,以确保它正确迭代预期的项目数。如果循环设置不正确,可能会导致意外的空值。

Mockito 参数匹配器: 确保您正确使用 Mockito 的参数匹配器 (argThat)。匹配器应该能够处理迭代期间传递的对象。如果您的匹配器无法处理空值,请考虑相应地更新它。

检查堆栈跟踪: 查看 NullPointerException 的完整堆栈跟踪,以确定导致问题的确切代码行。这可以提供更多关于哪个对象或方法调用导致空引用的上下文。

条件逻辑: 如果循环内有条件逻辑,请检查它是否正确处理不同的情况,包括空值的可能性。

© www.soinside.com 2019 - 2024. All rights reserved.