我尝试使用自定义的ArgumentMatcher,但总是得到NPE,对我来说,现在很难找到原因,即使我在文档中找到了相关的NPE。
@Test
void debug() {
class ListGetMatcher implements ArgumentMatcher<Integer> {
public boolean matches(Integer index) {
return index == 2;
}
}
List mock = mock(List.class);
when(mock.get(argThat(new ListGetMatcher()))).thenReturn(200);
assertEquals(200, mock.get(2));
//when(mock.addAll(argThat(new ListOfTwoElements()))).thenReturn(true);
//mock.addAll(Arrays.asList("one", "two"));
//verify(mock).addAll(argThat(new ListOfTwoElements()));
}
我只是改为使用intThat,它工作得很好。
doReturn(200).when(mock).get(intThat(new ListGetMatcher()));
但以下情况仍会引起NPE。
when(substationQueryExecutor.getSubById(argThat(argument -> argument.getId() == 1L))).thenReturn(new Substation());
当参数的id为999时,我希望返回Substation。我该怎么办?
下面是更详细的代码,我是getSubById()的stub,它有一个SubstationQueryCmd参数类型,我希望根据SubstationQueryCmd的id值返回不同的值。当我调试代码时,我发现matches()的回调总是传递给我一个null而不是SubstationQueryCmd对象。我不明白问题出在哪里,也许你知道。
@Slf4j
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE)
class SubPowerSaveExecutorTest {
@InjectMocks
private SubPowerSaveExecutor executor;
@Mock
private SubstationQueryExecutor queryExecutor;
@BeforeEach
public void setup() {
MockitoAnnotations.openMocks(this);
}
static class SubstationQueryArgMatcher implements ArgumentMatcher<SubstationQueryCmd> {
private final Long id;
public SubstationQueryArgMatcher(Long id) {
this.id = id;
}
@Override
public boolean matches(SubstationQueryCmd argument) {
// I debugged the code and found that the argument is null every time, I think this is the problem
return argument.getId().longValue() == id;
}
}
@Test
void test() {
when(queryExecutor.getSubById(argThat(new SubstationQueryArgMatcher(1L)))).thenReturn(new Substation());
when(queryExecutor.getSubById(argThat(new SubstationQueryArgMatcher(999L)))).thenReturn(null);
List<SubPowerDto> datas = new ArrayList<>();
datas.add(new SubPowerDto().setMeterNum("meter01").setProviderName("diehl").setDate("2022-04-24 10:10:00").setSubstationId(1L).setPower(1D));
datas.add(new SubPowerDto().setMeterNum("meter01").setProviderName("diehl").setDate("2022-04-24 10:20:00").setSubstationId(1L).setPower(1D));
datas.add(new SubPowerDto().setMeterNum("meter01").setProviderName("diehl").setDate("2022-04-24 10:30:00").setSubstationId(1L).setPower(1D));
datas.add(new SubPowerDto().setMeterNum("meter01").setProviderName("diehl").setDate("2022-04-24 10:30:00").setSubstationId(999L).setPower(1D));
// getSubById() will be called in filterData
List<SubPower> subPowers = executor.filterData(datas);
assertEquals(1, subPowers.size());
}
}
1条答案
按热度按时间s4n0splo1#
因为您使用
argThat
.作为源代码:要解决此问题,只需更改为使用
intThat
。你的第二个问题:您可能会误解
ArgumentMatcher
的用法。您的方法
queryExecutor.getSubById
的参数为Long
,但您使用:这是不正确的。请将其更改为:
然后,您可以使用
longThat
而不是argThat
。在
substationQueryExecutor.getSubById
的情况下,参数为SubstationQueryCmd
。然后,您只需要在自定义匹配器中选中
null
:因为:这是一个对象,它可能是
null
。所以,这发生在你试图存根的那一行。所以,如果你使用下面的语法,你需要在你的自定义参数匹配器中检查null
:若要避免变更自订参数比对器,您可以改为使用下列语法:
因此,您的代码应该是:
快乐编码!