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

izj3ouym  于 2024-01-07  发布在  其他
关注(0)|答案(2)|浏览(159)

其中一个遗留测试使用Mockito argThat在循环中存根对应的结果。
如果我将迭代次数减少到1(numberOfItems = 1,即如果没有循环),则通过。
当它到达第二次迭代时,它会用NPE出错:

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

字符串
代码如下:

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


正在测试的方法类似于以下内容

  1. public List<MyData> methodUnderTest(List<MyData> myDataList) {
  2. myDataList.forEach(myData -> {
  3. // ... some logic ...
  4. myData.setResult(mockedService.someMethod(new MyRequest(myData.getMyValue())));
  5. }
  6. });
  7. return myDataList;
  8. }


但是对于错误情况,方法调用甚至没有到达,因为NPE在单元测试代码中发生得更早。
最初它是通过被使用有点像这样

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


然而,我看到了一个建议,更喜欢直接比较对象,所以我试图按照建议重写编译,摆脱那些equalTohasProperty,bot现在进入了那些NPE错误:)
有什么建议我做错了吗?谢谢!!

sd2nnvve

sd2nnvve1#

当你第一次调用when(mockedService.someMethod(argThat(arg -> Objects.equals(arg.getValue(), md.getMyValue())))).thenReturn(getExpectedResult(md.getMyValue()));时,这个方法被存根化。当你第二次调用它时,现有的存根试图匹配第二次的存根化调用。argThat(和所有其他匹配器方法)返回null,这使得你现有的存根的匹配器抛出。
两种可能的解决方案:

  • 将匹配器更改为argThat(arg -> arg != null && ...)以不匹配空输入
  • 不要使用when(mock.call(argThat(...))).thenReturn(result)形式--它实际上调用了方法!--,而要切换到doReturn(result).when(mock).call(argThat(...))
mfuanj7w

mfuanj7w2#

从另一端解决了这个问题。
长话短说,这一切都是在我升级到Java 17和Mockito到5.3.1之后开始的,这使得argThat与hamcrest hasProperty不兼容,因为这些Matcher/ArgumentMatcher不兼容(https://stackoverflow.com/a/8351055/2518705)。
在这一点上,我决定取代那些火腿匹配和面对NPE。
现在我意识到,我可以通过使用org.mockito.hamcrest.MockitoHamcrest.argThat而不是org.mockito.ArgumentMatchers.argThat来使它工作。
同时,原始问题可能仍然有单独的正确答案:)

相关问题