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

发布于 2024-11-06 12:04:12 字数 519 浏览 4 评论 0原文

检查以下代码片段:

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

这断言列表中不存在不以“x”结尾的元素。当然,这是表示列表中所有元素都以“x”结尾的双重否定方式。

另请注意,该代码片段会抛出:

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

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

那么是否有一种惯用的方式:

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

Examine the following snippet:

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

This asserts that the list doesn't have an element that doesn't end with "x". This, of course, is the double negatives way of saying that all elements of the list ends with "x".

Also note that the snippet throws:

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

This lists the entire list, instead of just the element that doesn't end with "x".

So is there an idiomatic way of:

  • Asserting that each element ends with "x" (without double negatives)
  • On assertion error, list only those elements that doesn't end with "x"

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

烟花肆意 2024-11-13 12:04:12

您正在寻找 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"

You are looking for everyItem():

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

This produces a nice failure message:

Expected: every item is a string ending with "x"
     but: an item was "4z"
夜访吸血鬼 2024-11-13 12:04:12

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

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

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

    java.lang.AssertionError: 
    预期:不是不包含以“x”结尾的字符串的集合
         得到:<[1x, 2x, 3x, 4z]>
    
  • 使用 everyItem(...) 匹配器:

    java.lang.AssertionError: 
    预期:每个项目都是以“x”结尾的字符串
         得到:<[1x, 2x, 3x, 4z]>
    

来自 Hamcrest 的匹配器 (org.hamcrest.MatcherAssert.assertThat) 产生 David 给出的输出:

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

    java.lang.AssertionError: 
    预期:不是不包含以“x”结尾的字符串的集合
         但是:是<[1x, 2x, 3x, 4z]>
    
  • 使用 everyItem(...) 匹配器:

    java.lang.AssertionError: 
    预期:每个项目都是以“x”结尾的字符串
         但是:一个项目是“4z”
    

我自己对 Hamcrest 断言的实验表明,“但是”部分经常令人困惑,具体取决于多个匹配器的精确程度组合起来,哪个先失败,因此我仍然坚持 JUnit 断言,我非常清楚我将在“得到”部分看到什么。

The matcher given by David Harkness produces a nice message for the expected part.
The message for the actual part, however, is also determined by which assertThat method you use:

The one from JUnit (org.junit.Assert.assertThat) produces the output you provided.

  • With the not(hasItem(not(...))) matcher:

    java.lang.AssertionError: 
    Expected: not a collection containing not a string ending with "x"
         got: <[1x, 2x, 3x, 4z]>
    
  • With the everyItem(...) matcher:

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

The one from Hamcrest (org.hamcrest.MatcherAssert.assertThat) produces the output given by David:

  • With the not(hasItem(not(...))) matcher:

    java.lang.AssertionError: 
    Expected: not a collection containing not a string ending with "x"
         but: was <[1x, 2x, 3x, 4z]>
    
  • With the everyItem(...) matcher:

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

My own experimentation with the Hamcrest assert showed me that the "but" part is often confusing, depending on how exactly multiple matchers are combined and which one fails first, and therefore I still stick to the JUnit assert, where I know quite exactly what I'll see in the "got" part.

凉栀 2024-11-13 12:04:12

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

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

这就是原因。

I know this question is quite old, but today, with Java 8, I'd rather write it with lambdas, e.g.

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

This is why.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文