I am trying to do the following.
final Matcher<SuperClass> matcher1 = Matchers.hasProperty("a", equalTo("b"));
final Matcher<SuperClass> matcher2 = Matchers.hasProperty("c", equalTo("d"));
final Matcher<SuperClass> matchers = Matchers.allOf(matcher1, matcher2);
List<SubClass> list = someStuff();
assertThat(list, everyItem(matchers));
I am getting a compilation error on the assert line, is there any easy way to get rid of this.
@SuppressWarnings({"unchecked", "rawtypes"})
@Test public void yourTest() {
final Matcher<SuperClass> matcher1 = Matchers.hasProperty("a", equalTo("b"));
final Matcher<SuperClass> matcher2 = Matchers.hasProperty("c", equalTo("d"));
final Matcher<SuperClass> matchers = Matchers.allOf(matcher1, matcher2);
List<SubClass> list = someStuff();
// Note cast to raw type here, corresponding to the suppressed warnings.
assertThat(list, (Matcher) everyItem(matchers));
}
// These are all of type Matcher<SubClass> instead.
final Matcher<SubClass> matcher1 = Matchers.hasProperty("a", equalTo("b"));
final Matcher<SubClass> matcher2 = Matchers.hasProperty("c", equalTo("d"));
final Matcher<SubClass> matchers = Matchers.allOf(matcher1, matcher2);
List<SubClass> list = someStuff();
assertThat(list, everyItem(matchers));
Why? Java's generics handling is too clever for Hamcrest. everyItem(matchers)
will return a Matcher<Iterable<SuperClass>>
, but you don't have an Iterable<SuperClass>
, you have an Iterable<SubClass>
. It would all be fine if you actually had your Matcher methods produce a Matcher<Iterable<? extends SuperClass>>
, but it's nearly impossible for you to convince Java that your matcher1
and matcher2
are compatible with one another.