Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I get contains(List<Matcher> itemMatchers) to compile in Java 7?

Tags:

java

hamcrest

I am learning Hamcrest 1.3 and I want to come up with an example for each Hamcrest static method in Matchers. The Javadoc helpfully already has examples for some methods. I tested the following contains code snippet with Java 8 and it passed:

assertThat(Arrays.asList("foo", "bar"), 
           contains(Arrays.asList(equalTo("foo"), equalTo("bar"))));

However, my team is currently using Java 7 so I wanted to make sure all the examples work in that version. The above code snippet produces the following error in Java 7:

no suitable method found for assertThat(java.util.List,org.hamcrest.Matcher>>>) method org.junit.Assert.assertThat(T,org.hamcrest.Matcher) is not applicable (actual argument org.hamcrest.Matcher>>> cannot be converted to org.hamcrest.Matcher> by method invocation conversion) method org.junit.Assert.assertThat(java.lang.String,T,org.hamcrest.Matcher) is not applicable (cannot instantiate from arguments because actual and formal argument lists differ in length)

I know that Java 8 added new implicit typing features for static methods and I think this is likely related. I have attempted to refactor out parameters and casting them to the expected arguments, but that results in the same error:

List<String> actual = Arrays.asList("foo", "bar");
List<Matcher<String>> expected = Arrays.asList(equalTo("foo"), 
                                               equalTo("bar"));
assertThat(actual, contains(expected));

What is the proper way to call static <E> Matcher<java.lang.Iterable<? extends E>> contains(java.util.List<Matcher<? super E>> itemMatchers) in Java 7?

like image 721
BennyMcBenBen Avatar asked Jun 10 '14 03:06

BennyMcBenBen


1 Answers

In the Hamcrest Javadoc, the method signature for the contains() that you're targeting is:

 public static <E> Matcher<Iterable<? extends E>> contains(List<Matcher<? super E>> itemMatchers);

The important bit to note in the above signature is the List<Matcher<? super E>>. Java 7 cannot infer List<Matcher<? super E>> from List<Matcher<String>>. The contains() is additionally overloaded, so the signature of the method that Java 7 targets is:

public static <E> Matcher<Iterable<? extends E>> contains(E... items);

And this is the reason you're getting the cryptic compilation error message!

Fortunately, the fix is pretty straightforward:

List<String> actual = Arrays.asList("foo", "bar");
List<Matcher<? super String>> expected = Arrays.<Matcher<? super String>>asList(equalTo("foo"), 
                                                                                equalTo("bar"));
assertThat(actual, contains(expected));
like image 136
Muel Avatar answered Nov 14 '22 22:11

Muel