如何检查hamcrest

时间:2016-10-21 12:40:51

标签: java junit hamcrest

我使用Hamcrest 1.3并尝试以更紧凑的方式实现以下目标。

考虑以下测试用例:

@Test
public void testCase() throws Exception {

    Collection<String> strings = Arrays.asList(
        "string one",
        "string two",
        "string three"
    );

    // variant 1:
    assertThat(strings, hasSize(greaterThan(2)));
    assertThat(strings, hasItem(is("string two")));

    // variant 2:
    assertThat(strings, allOf(
        hasSize(greaterThan(2)),
        hasItem(is("string two"))
    ));
}

这里的目标是检查集合的大小和要包含的一些特定项目。

如果第一个变体是可能的并且被接受,那么它并不总是那么容易,因为集合本身可能是其他一些操作的结果,因此使用{{{{{{{{ 1}}操作。这是在上面的第二个变体中完成的。

但是,包含第二个变体的代码将导致以下编译时错误:

allOf

是否有任何特定的方法在Hamcrest中使用单击操作(如error: no suitable method found for allOf(Matcher<Collection<? extends Object>>,Matcher<Iterable<? extends String>>) )测试集合的大小和项目?

4 个答案:

答案 0 :(得分:8)

我认为编译器无法整理泛型。以下是为我工作(JDK 8u102):

assertThat(strings, Matchers.<Collection<String>> allOf(
    hasSize(greaterThan(2)),
    hasItem(is("string two"))
));

答案 1 :(得分:1)

我知道这个问题很旧,但是我仍然想回答这个问题,以防有人需要解释。

如果要使用allOf(...),只需确保嵌套匹配器返回的类型匹配即可。在您的测试用例中,hasSize返回org.hamcrest.Matcher<java.util.Collection<? extends T>>,但是hasItem产生org.hamcrest.Matcher<java.lang.Iterable<? super T>>。 在这种情况下,我建议使用返回类型为Matcher<java.lang.Iterable<T>>的{​​{3}},所以您可以这样做:

assertThat(strings, allOf( iterableWithSize(greaterThan(2)), hasItem("string two") ) );

答案 2 :(得分:0)

猜测:你不会通过使用现有的匹配器来实现目标。

但是一旦你理解了事情是如何结合起来的,那么写你自己的匹配器只需要几分钟。

也许你看看我的另一个answer;在那里我举一个完整的例子,如何编写自己的匹配器。那时候,我花了15分钟;虽然我以前从未写过自定义匹配器。

答案 3 :(得分:0)

有一种简单但老实的隐藏方式来测试列表大小和匹配项:contains

contains和一个Matcher,检查可迭代对象(例如列表)是否只有一项,并且该项目与给定的Matcher匹配

contains(E... items)(任意数量的Matchers)检查可迭代对象是否具有AS MANY个项目(与给定的Matchers数量相同,并且每个项目都与给定的Matchers之一匹配)。请注意,匹配器不能匹配多个项目,否则结果可能与您预期的不一样

因此,总结contains会隐式检查大小是否正确(根据给定的Matchers数量)

如果您对给定的大小匹配不感兴趣,请使用hasItem/hasItems