Mockito and Hamcrest: how to verify invocation of Collection argument?

generics, hamcrest, java, mockito

Solution

You can just write

verify(service).perform((Collection<String>) Matchers.argThat(contains("a", "b")));

From the compiler's point of view, this is casting an `Iterable<String>` to a `Collection<String>` which is fine, because the latter is a subtype of the former. At run time, `argThat` will return `null`, so that can be passed to `perform` without a `ClassCastException`. The important point about it is that the matcher gets onto Mockito's internal structure of arguments for verification, which is what `argThat` does.

Problem

I'm running into a generics problem with Mockito and Hamcrest. Please assume the following interface: ``` public interface Service { void perform(Collection<String> elements); } ``` And the following test snippet: ``` Service service = mock(Service.class); // ... perform business logic verify(service).perform(Matchers.argThat(contains("a", "b"))); ``` So I want to verify that my business logic actually called the service with a collection that contains "a" and "b" in that order. However, the return type of `contains(...)` is `Matcher<Iterable<? extends E>>`, so `Matchers.argThat(...)` returns `Iterable<String>` in my case, which naturally does not apply to the required `Collection<String>`. I know that I could use an argument captor as proposed in Hamcrest hasItem and Mockito verify inconsistency, but I would very much like not to. Any suggestions! Thanks!

Original source