Java 使用匹配器的mockito的InvalidUseOfMatcherException

Java 使用匹配器的mockito的InvalidUseOfMatcherException,java,mockito,matcher,Java,Mockito,Matcher,我正在与mockito合作,我将获得下一期: java.lang.AssertionError: Expected: (an instance of java.lang.IllegalArgumentException and exception with message a string containing "") but: an instance of java.lang.IllegalArgumentException <org.mockito.exceptions.m

我正在与mockito合作,我将获得下一期:

java.lang.AssertionError: 
Expected: (an instance of java.lang.IllegalArgumentException and exception with message a string containing "")
     but: an instance of java.lang.IllegalArgumentException <org.mockito.exceptions.misusing.InvalidUseOfMatchersException: 
Invalid use of argument matchers!
0 matchers expected, 1 recorded:
-> at com.rccl.middleware.kidsclub.engine.services.KidServiceTest.saveKid_kidExist_throwException(KidServiceTest.java:97)

This exception may occur if matchers are combined with raw values:
    //incorrect:
    someMethod(anyObject(), "raw String");
When using matchers, all arguments have to be provided by matchers.
For example:
    //correct:
    someMethod(anyObject(), eq("String by matcher"));
这是saveKid方法的代码,该方法基本上发送异常:

       if (!validateShipRoomExist()) {
            log.warn("::: The ShipRoom document doesn't exist.");
            throw new RoomNotFoundException(NO_ROOMS_IN_DATABASE);
        }

        if (validateKidAlreadyRegistered(kidDTO.getId())) {
            log.warn("::: Trying to persist a Kid already persisted with ID [{}]", kidDTO.getId());
            throw new IllegalArgumentException(String.format("Kid already registered with ID [%s]", kidDTO.getId()));
        }
这些方法被称为:

        private boolean validateShipRoomExist() {
            return roomService.existShipRoomDefault();
        }

        public boolean validateKidAlreadyRegistered(@NotNull String kidId) {
            return kidRepository.existsById(kidId);
        }
接下来是我在roomService中的代码:

public boolean existShipRoomDefault() {
        return roomRepository.existsById(DEFAULT_AGGREGATOR_ID);
 }

问题出在这个有问题的方法中,尽管我在这个测试中使用了字符串anyString()。我不明白这件事发生了什么。一个有趣的想法是,在调试模式下,如果我有一个断点,测试不会失败。

BDDMockito.startsWith
是一个匹配器方法,您在与模拟无关的
expectedException.expectMessage
上使用了该方法

如果要评估异常消息,应将其与完整消息进行比较

调整后的测试可能如下所示:

@Test
public void saveKid_kidExist_throwException() {

    // ...

    KidDTO kidDto = new KidDTO();
    kidDto.setId("1");

    expectedException.expect(IllegalArgumentException.class);
    expectedException.expectMessage("Kid already registered with ID [1]");
    service.saveKid(kidDto);
}
因为我不知道MockDTO类在做什么,而且我假设自己创建
KidDTO
的实例很容易,所以我在上面的示例中就是这么做的

另一种选择是——如果
kidDTO
是一个模拟——定义:

BDDMockito.given(kidDto.getId()).willReturn("1");

好的,我也这么认为,但我需要评估错误消息,还有其他方法吗?谢谢。kidto是用MockDTO类中的信息创建的新对象,这就是你的意思吗?呃,什么类型是
expectedException
。然后是什么(kidRepository).should().existsById(anyString())应该做什么?@GhostCat:我想它和行应该是
existsById
方法上的验证。但由于异常处理的工作方式,无法访问它。
BDDMockito.given(kidDto.getId()).willReturn("1");