什么是惯用的 Hamcrest 模式来断言可迭代的每个元素都匹配给定的匹配器?

Posted

技术标签:

【中文标题】什么是惯用的 Hamcrest 模式来断言可迭代的每个元素都匹配给定的匹配器?【英文标题】:What is the idiomatic Hamcrest pattern to assert that each element of an iterable matches a given matcher? 【发布时间】:2011-08-24 13:03:39 【问题描述】:

检查以下 sn-p:

    assertThat(
        Arrays.asList("1x", "2x", "3x", "4z"),
        not(hasItem(not(endsWith("x"))))
    );

这断言列表中没有不以“x”结尾的元素。当然,这是双重否定的说法,即列表的所有元素都以“x”结尾。

还要注意 sn-p 抛出:

java.lang.AssertionError: 
Expected: not a collection containing not a string ending with "x"
     got: <[1x, 2x, 3x, 4z]>

这会列出整个列表,而不仅仅是不以“x”结尾的元素。

那么有没有一种惯用的方式:

断言每个元素都以“x”结尾(没有双重否定) 在断言错误时,仅列出那些不以“x”结尾的元素

【问题讨论】:

【参考方案1】:

您正在寻找everyItem():

assertThat(
    Arrays.asList("1x", "2x", "3x", "4z"),
    everyItem(endsWith("x"))
);

这会产生一个很好的失败消息:

Expected: every item is a string ending with "x"
     but: an item was "4z"

【讨论】:

【参考方案2】:

David Harkness 给出的匹配器为预期的部分生成了一个很好的消息。 但是,实际部分的消息也取决于您使用的assertThat 方法:

JUnit (org.junit.Assert.assertThat) 产生您提供的输出。

使用not(hasItem(not(...))) 匹配器:

java.lang.AssertionError: 
Expected: not a collection containing not a string ending with "x"
     got: <[1x, 2x, 3x, 4z]>

使用everyItem(...) 匹配器:

java.lang.AssertionError: 
Expected: every item is a string ending with "x"
     got: <[1x, 2x, 3x, 4z]>

Hamcrest (org.hamcrest.MatcherAssert.assertThat) 产生了 David 给出的输出:

使用not(hasItem(not(...))) 匹配器:

java.lang.AssertionError: 
Expected: not a collection containing not a string ending with "x"
     but: was <[1x, 2x, 3x, 4z]>

使用everyItem(...) 匹配器:

java.lang.AssertionError: 
Expected: every item is a string ending with "x"
     but: an item was "4z"

我自己对 Hamcrest 断言的实验表明,“但是”部分经常令人困惑,这取决于多个匹配器的组合方式以及哪个匹配器首先失败,因此我仍然坚持使用 JUnit 断言,我对此非常了解正是我将在“得到”部分看到的。

【讨论】:

【参考方案3】:

我知道这个问题已经很老了,但是今天,使用 Java 8,我宁愿用 lambdas 编写它,例如

Stream.of("1x", "2x", "3x", "4z").allMatch(e->e.endsWith("x"));

This is why.

【讨论】:

好收获。但在我看来,Harmcrest 仍然会获胜,因为它的失败消息会更详细地说明哪个项目失败以及失败的原因。当然,如果有时间能看到文章中提到的这种 java8 风格的 assertThat API,当然会很好。

以上是关于什么是惯用的 Hamcrest 模式来断言可迭代的每个元素都匹配给定的匹配器?的主要内容,如果未能解决你的问题,请参考以下文章

03-10 断言

Hamcrest 总结

JUnitJUnit Hamcrest 断言

Hamcrest 断言

Hamcrest 断言

有没有一种惯用的方法来断言流只有一个元素而产生该元素? [复制]