Elad Benda2 Elad Benda2 - 5 months ago 20
Java Question

how can I call a custom hamcrest matcher?

I want to check when a mock is called with a

realtimeUpdate
which
currentTime
field equals some
LocalDateTime
:

I want to run such code with a custom matcher:

verify(mockServerApi).sendUpdate(new TimeMatcher().isTimeEqual(update, localDateTime2));


but I have a compilation error when I try to run with this custom matcher.

How can I fix this?

public class TimeMatcher {

public Matcher<RealtimeUpdate> isTimeEqual(RealtimeUpdate realtimeUpdate, final LocalDateTime localDateTime) {
return new BaseMatcher<RealtimeUpdate>() {
@Override
public boolean matches(final Object item) {
final RealtimeUpdate realtimeUpdate = (RealtimeUpdate) item;
return realtimeUpdate.currentTime.equalTo(localDateTime);
}


this is the method signature

void sendRealTimeUpdate(RealtimeUpdate realtimeUpdate);


and this is the compilation error:

enter image description here

Answer

Here is how you could proceed

The class TimeMatcher, you need only the LocalDateTime

public class TimeMatcher {
    public static Matcher<RealtimeUpdate> isTimeEqual(final LocalDateTime localDateTime) {
        return new BaseMatcher<RealtimeUpdate>() {
            @Override
            public void describeTo(final Description description) {
                description.appendText("Date doesn't match with "+ localDateTime);
            }

            @Override
            public boolean matches(final Object item) {
                final RealtimeUpdate realtimeUpdate = (RealtimeUpdate) item;
                return realtimeUpdate.currentTime.isEqual(localDateTime);
            }
        };
    }
}

The test:

Mockito.verify(mockRoutingServerApi).sendRealTimeUpdate(
    new ThreadSafeMockingProgress().getArgumentMatcherStorage()
        .reportMatcher(TimeMatcher.isTimeEqual(localDateTime2))
        .returnFor(RealtimeUpdate.class));

You need to use returnFor to return an object of type RealtimeUpdate as expected by sendRealTimeUpdate

This is equivalent to:

Mockito.verify(mockRoutingServerApi).sendRealTimeUpdate(
    Matchers.argThat(TimeMatcher.isTimeEqual(localDateTime2))
);