Conflicting overloading of Java – hamcrest matcher
The matcher isiterablecontaininginanyorder has two overloads on the static factory method containsinanyorder (both have the return type matcher < Java. Lang. Iterable >):
> containsInAnyOrder(java.util.Collection< Matcher<?super T>> itemMatchers) > containsInAnyOrder(Matcher<?super T> … itemMatchers)
Now consider the following procedure:
import static org.hamcrest.collection.IsIterableContainingInAnyOrder.containsInAnyOrder; import static org.hamcrest.core.IsEqual.equalTo; import static org.junit.Assert.assertThat; import java.util.Arrays; import org.junit.Test; public class SomeTest { @SuppressWarnings("unchecked") @Test public void foo() { assertThat(Arrays.asList("foo","bar"),containsInAnyOrder(equalTo("foo"),equalTo("bar"))); } }
When it is executed as a JUnit test, it passes as expected It uses the second overload of containsinanyorder shown above
Now, when I change the assertion to this time (exactly matching the example given in the documentation of the first overload):
assertThat(Arrays.asList("foo",containsInAnyOrder(Arrays.asList(equalTo("foo"),equalTo("bar")))); ^^^^^^^^^^^^^^
It no longer compiles because the compiler now infers the return type of containsinanyorder
Matcher<Iterable<? extends List<Matcher<String>>>>
It seems that the compiler still chooses the second overload If it uses the first example, it should be valid Why is it like this? How can I do this?
I use hamcrest 1.3 and Oracle Java 1.7
Solution
It actually matches two overloaded methods I'm not sure why I choose the first one, but you can provide a hint to let it choose the right method
By casting parameters to collection:
assertThat(Arrays.asList("foo",containsInAnyOrder((Collection)Arrays.asList(equalTo("foo"),equalTo("bar"))));
Or specify the generic type T as < string > (but static import cannot be used):
assertThat(Arrays.asList("foo",IsIterableContainingInAnyOrder.<String>containsInAnyOrder(Arrays.asList(equalTo("foo"),equalTo("bar"))));