-
-
Notifications
You must be signed in to change notification settings - Fork 2.6k
Open
Labels
Milestone
Description
Assume we have the following test.
@Mock
private Consumer<Collection<?>> consumer;
@Test
public void test() throws Exception {
consumer.accept(new HashSet<>());
consumer.accept(new ArrayList<>());
ArgumentCaptor<ArrayList<?>> captor = ArgumentCaptor.forClass(ArrayList.class);
verify(consumer).accept(captor.capture());
}
The test fails with:
org.mockito.exceptions.verification.TooManyActualInvocations:
consumer.accept(<Capturing argument>);
Wanted 1 time:
-> at foo.TestClass.testName(TestClass.java:64)
But was 2 times. Undesired invocation:
-> at agh.TestClass.testName(TestClass.java:61)
at foo.TestClass.test(TestClass.java:64)
[..]
The test fails because the ArgumentCaptor stores every type, because the type information is erased a runtime. How can we capture the type that is specified in the captor, in this case ArrayList
? It is possible to implement an Answer
that stores the argument, and use
Matchers.isA(ArrayList.class)
but thats ugly->
doAnswer(captureArg1).when(consumer).accept(isA(ArrayList.class));
Maybe it is a good idea to create a pull req and extend the ArgumentCaptor API by adding a method like <T> T captureIf(ArgumentMatcher<? extends T>)
?
Then we could write:
verify(consumer).accept(captor.captureIf(isA(ArrayList.class)));
CarlSalaets, timxmur and lesiak