Question

I've ran into an issue with hamcrest and mockito. Here is what I'm trying to do:

public class A{
     public void foo(List<B> arg){
          return;
     }
}

public BMatcher extends BaseMatcher<B>{
 //Some impl...
}

In my test I want to do something like

A a = mock(A.class);
B expected = new B();
Mockito.verify(a).foo(argThat(JUnitMatchers.hasItem(new BMatcher(expected)));

However, the hasItem matcher returns an Iterable<B> while the foo method expects a List<B>. Is there any good way of verifying the method is called properly?

Was it helpful?

Solution

You could use an ArgumentCaptor.

 @Captor
 ArgumentCaptor<List<B>> captor;

 // then in test
 ...
 verify(a).foo(captor.capture());
 List<B> values = captor.getValue();
 assertThat(values, IsIterableContainingInOrder.containingInOrder(new BMatcher(expected));
 ...

I used the @Captor as a shortcut and also to that it could be a List<B> instead of just List. This requires the use of MockitoAnnotations.init(this) in an @Before method.

OTHER TIPS

You can use the 'argThat' method in the Mockito Matchers class to convert from a hamcrest Matcher to a mockito argument matcher:

import static org.mockito.Matchers.argThat;
import org.hamcrest.Matchers;
import org.hamcrest.Matcher;
//....
public static <T> List<T> listWithItem(Matcher<T> m)
{
    return (List<T>)argThat(Matchers.hasItem(m));
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top