Is there a way to capture a list of specific type using mockitos ArgumentCaptore. This doesn't work:
ArgumentCaptor<ArrayList<SomeType>> argument = ArgumentCaptor.forClass(ArrayList.class);
The nested generics-problem can be avoided with the @Captor annotation:
public class Test{ @Mock private Service service; @Captor private ArgumentCaptor<ArrayList<SomeType>> captor; @Before public void init(){ MockitoAnnotations.initMocks(this); } @Test public void shouldDoStuffWithListValues() { //... verify(service).doStuff(captor.capture())); } }
Yeah, this is a general generics problem, not mockito-specific.
There is no class object for ArrayList<SomeType>
, and thus you can't type-safely pass such an object to a method requiring a Class<ArrayList<SomeType>>
.
You can cast the object to the right type:
Class<ArrayList<SomeType>> listClass = (Class<ArrayList<SomeType>>)(Class)ArrayList.class; ArgumentCaptor<ArrayList<SomeType>> argument = ArgumentCaptor.forClass(listClass);
This will give some warnings about unsafe casts, and of course your ArgumentCaptor can't really differentiate between ArrayList<SomeType>
and ArrayList<AnotherType>
without maybe inspecting the elements.
(As mentioned in the other answer, while this is a general generics problem, there is a Mockito-specific solution for the type-safety problem with the @Captor
annotation. It still can't distinguish between an ArrayList<SomeType>
and an ArrayList<OtherType>
.)
Take also a look at tenshi's comment. You can change the original code to this simplified version:
final ArgumentCaptor<List<SomeType>> listCaptor = ArgumentCaptor.forClass((Class) List.class);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With