Hamcrest:如何在Collections中使用/或可组合的匹配器

时间:2018-06-30 15:25:33

标签: java junit junit4 matcher hamcrest

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

@Test
public void EitherOrMatcherSimple() {
    List<String> keywords = Arrays.asList("1");
    assertThat(keywords, CombinableMatcher.either(empty()).
                                           or(nullValue()).
                                           or(both(hasItem("1")).and(hasItem("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>>)

所以,我不知道如何使用该方法,无论它期望作为参数是什么。我知道.or()方法使用Matcher<? super X> other作为参数,这对我来说尚不清楚。

我只是知道引入了一个或两个方法和/或两个方法,以使用&&||运算符更好地编写和读取Java条件。

有人可以解释一下吗?

1 个答案:

答案 0 :(得分:2)

有时很难组合Hamcrest匹配器的类型安全性。您的示例就是其中一种情况。如果没有显式的强制转换,可能甚至不可能做到正确。

这是摆脱编译器问题的解决方案:

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

如果我理解正确,那么问题是hasItem的签名过于严格:

org.hamcrest.Matcher<java.lang.Iterable<? super T>> hasItem(T item)