我正在尝试执行以下操作。
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));
我在断言行上遇到编译错误,有没有简单的方法来摆脱它。
答案 0 :(得分:2)
@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));
为什么? Java的泛型处理对于Hamcrest来说太聪明了。 everyItem(matchers)
会返回Matcher<Iterable<SuperClass>>
,但您没有Iterable<SuperClass>
,而是Iterable<SubClass>
。如果你实际上你的Matcher方法产生了Matcher<Iterable<? extends SuperClass>>
,那一切都会好的,但是你几乎不可能让Java相信你的matcher1
和matcher2
是相互兼容的。
答案 1 :(得分:0)
泛型。
您的代码的问题在于您尝试断言类型为List<SubClass>
的列表与匹配Matcher<SuperClass>
的匹配器的每个项目匹配。
即使SuperClass
扩展SubClass
,assertThat
方法也要求两者相同。
因此,如果您强制使用someStuff()
方法返回SuperClass
的列表,那么您应该免费回家。即像这样的东西
List<SuperClass> list = someStuff();
assertThat(list, everyItem(matchers));
将摆脱编译错误。