I am trying to verify a mocked service was called with an arguments in which the last is an iterator. This is the assertion in the test:
verify(myService).myMethod(
...,
argThat(dataIterator -> iteratorEquals(dataIterator, dataToSave.iterator())));
and I have this TestHelper method:
public class TestHelpers {
public static <T> boolean iteratorEquals(Iterator<T> x, Iterator<T> y) {
while (x.hasNext() && y.hasNext()) {
if (x.next() != y.next()) {
return false;
}
}
return x.hasNext() == y.hasNext();
}
}
I was debugging the static method and it seems like the value returned from it is indeed true
. Also, when debugging I can see the arguments passed to the service are as expected, but the assertion for some reason will fail in this case.
When I am changing the assertion to this:
verify(myService).myMethod(
...,
any());
the test will pass, meaning the problem is, indeed, with the iterator argument. This is the error I receive when the test fails:
myService.myMethod( ..., <custom argument matcher> ); Wanted 1 time: -> at ...(StorageClientTest.java:91) But was 0 times.
org.mockito.exceptions.verification.TooFewActualInvocations: myService.myMethod( ..., <custom argument matcher> ); Wanted 1 time: -> at ...(StorageClientTest.java:91) But was 0 times.
Am I doing something wrong here? why does the test fail?
The solution to this issue is to change the signature of the generic help method to return ArgumentMatcher
and to move the lambda expression inside it:
public <T> ArgumentMatcher<Iterator<T>> equalsIterator(Iterator<T> compareTo) {
return x -> {
while (x.hasNext() && compareTo.hasNext()) {
if (x.next() != compareTo.next()) {
return false;
}
}
return x.hasNext() == compareTo.hasNext();
};
}
and I am calling it this way:
verify(myService).myMethod(
...,
argThat(equalsIterator(dataToSave.iterator())));