Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to capture a list of specific type with mockito

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); 
like image 255
Andreas Köberle Avatar asked Apr 09 '11 17:04

Andreas Köberle


Video Answer


2 Answers

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()));     } } 
like image 191
crunchdog Avatar answered Sep 23 '22 09:09

crunchdog


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>.)

Edit:

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); 
like image 34
Paŭlo Ebermann Avatar answered Sep 25 '22 09:09

Paŭlo Ebermann