Java Hamcrest:如何在集合中使用/或组合匹配器

Java Hamcrest:如何在集合中使用/或组合匹配器,java,junit,junit4,matcher,hamcrest,Java,Junit,Junit4,Matcher,Hamcrest,我正在编写一些JUnit/Akruillian类测试,用Hibernate测试一些持久性方法。因此,我必须从数据库中获取许多Hibernate实体列表,并且为了更好地编写测试,我正在使用JUnit Hamcrest框架。 在这一刻,我想使用组合匹配器,特别是其中之一。我知道我可以用anyOf()方法替换它,但出于代码易读性的原因,我更喜欢组合匹配器。 我不明白如何使用或()。下面是一个简单的例子: @Test public void EitherOrMatcherSimple() { L

我正在编写一些JUnit/Akruillian类测试,用Hibernate测试一些持久性方法。因此,我必须从数据库中获取许多Hibernate实体列表,并且为了更好地编写测试,我正在使用JUnit Hamcrest框架。 在这一刻,我想使用组合匹配器,特别是其中之一。我知道我可以用
anyOf()
方法替换它,但出于代码易读性的原因,我更喜欢组合匹配器。 我不明白如何使用
或()。下面是一个简单的例子:

@Test
public void EitherOrMatcherSimple() {
    List<String> keywords = Arrays.asList("1");
    assertThat(keywords, CombinableMatcher.either(empty()).
                                           or(nullValue()).
                                           or(both(hasItem("1")).and(hasItem("2"))));
}
@测试
public void EitherOrMatcherSimple(){
列表关键字=数组。asList(“1”);
assertThat(关键字,CombinableMatcher.other(empty())。
或(空值()。
或(同时包括(第1项)和(第2项);
}
这样,我总是从Eclipse中得到一个错误,如:

The method or(Matcher<? super Collection<? extends Object>>) in the type CombinableMatcher<Collection<? extends Object>> is not applicable for the arguments (CombinableMatcher<Iterable<? super String>>)

方法或(Matcher有时很难将Hamcrest matchers与类型安全相结合。您的示例就是其中之一。如果没有显式转换,甚至可能无法正确执行

这是一个解决编译器问题的解决方案:

assertThat(
    keywords,
    CombinableMatcher.either(empty())
                     .or(nullValue())
                     .or((Matcher<? super Collection<?>>) both(hasItem("1")).and(hasItem("2")))
);

有趣的问题。您使用的是哪一版本的Java?如果是Java 7,您可能需要这些方法调用或强制转换中的一些类型提示。如果没有这些帮助,请在周一给我留言。然后我会仔细看一看。假设这行得通……这基本上也是我会尝试的!非常感谢您的友好回答。现在我开始理解开发人员对于“泛型地狱”的含义。无论如何,在这种情况下,最难理解的是
.and()
.or()
方法似乎分别从
中推断LHS的类型
方法,它们必须相同。我的意思是,我不能这样写:
断言(关键字,要么(empty())。要么(nullValue())。要么(hasSize(1))。和((Matcher)hasItem(“2”)));
没有对泛型
匹配器的隐式转换和
@SuppressWarnings({“unchecked”,“rawtypes”))
annotation…它毕竟没有那么强大。
org.hamcrest.Matcher<java.lang.Iterable<? super T>> hasItem(T item)