简体   繁体   中英

InvalidUseOfMatchersException with mockito using matchers

I am working with mockito and I am getting the next issue:

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"));

This is my test code:

    @Mock
    private KidRepository kidRepository;

    @Mock
    private RoomService roomService;

    @Test
    public void saveKid_kidExist_throwException() {
        given(kidRepository.existsById(anyString())).willReturn(true);
        given(roomService.existShipRoomDefault()).willReturn(true);

        expectedException.expect(IllegalArgumentException.class);
        expectedException.expectMessage(startsWith("Kid already registered"));
        KidDTO kidDTO = MockDTO.buildKidDTO();

        service.saveKid(kidDTO);

        then(kidRepository).should().existsById(anyString());
    }

This is the code of the saveKid method which is sending exceptions basically:

       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()));
        }

And these are the methods called:

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

        public boolean validateKidAlreadyRegistered(@NotNull String kidId) {
            return kidRepository.existsById(kidId);
        }

The next is my code in the roomService:

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

The problem is in this method which has the problem, even though I am using a string anyString() in this test. I don't understand what is happening in this case. an interesting think is that in debug mode the test doesn't fails if I have a breakpoint.

BDDMockito.startsWith is a Matcher method, which you used on expectedException.expectMessage which is unrelated to mocking.

If you want to evaluate the message of the exception you should compare it to the complete message.

An adjusted test could look like this:

@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);
}

Since I don't know what the MockDTO class is doing and I assume its easy to create an instance of KidDTO on your own, I just do that in the example above.

An alternative would be - in case kidDTO is a mock - to define:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM