Mockito/JMockit & Hamcrest matchers : How to verify Lists/Collections?

Eric B. picture Eric B. · Oct 26, 2015 · Viewed 10.5k times · Source

This 2013 post on SO asked how to use Hamcrest matchers to verify lists/collections invocations in Mockito. The accepted solution was to cast the Matcher to a (Collection).

I'm trying to do something similar, but running into a class cast error. I am not sure if I am misusing Hamcrest matchers, or if this usage simply isn't supported by Mockito. In my case, I'm trying to use a list of Matchers as my argument:

static class Collaborator
{
   void doSomething(Iterable<String> values) {}
}

@Test
public void usingMockito()
{
   Collaborator mock = Mockito.mock(Collaborator.class);
   mock.doSomething(Arrays.asList("a", "b"));

   // legal cast
   Mockito.verify(mock).doSomething((Collection<String>)argThat(Matchers.contains("a", "b")));
   // legal cast
   Mockito.verify(mock).doSomething((Collection<String>)argThat(Matchers.contains(Matchers.equalTo("a"), Matchers.equalTo("b"))));

   // illegal cast!!! Cannot cast from Iterable<capture#3-of ? extends List<Matcher<String>>> to Collection<String>
   Mockito.verify(mock).doSomething((Collection<String>)argThat(Matchers.contains(Arrays.asList(Matchers.equalTo("a"), Matchers.equalTo("b")))));
}

But I get the cast error:

Cannot cast from Iterable<capture#3-of ? extends List<Matcher<String>>> to Collection<String>

Am I doing something unsupported?

Answer

sendon1982 picture sendon1982 · Nov 20, 2017

I would prefer use allOf

import static org.hamcrest.Matchers.allOf;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.hasItems;
import static org.hamcrest.Matchers.hasProperty;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.notNullValue;
import static org.hamcrest.Matchers.nullValue;

...

    Mockito.verify(mock).doSomething(
        argThat(
            allOf(
                hasItems(equalTo("a")),
                hasItems(equalTo("b"))
            )
        )
    );