Каков идиоматический шаблон Hamcrest, чтобы утверждать, что каждый элемент итерируемого соответствует данному сопоставителю? - PullRequest
25 голосов
/ 13 мая 2011

Изучите следующий фрагмент:

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

Это подтверждает, что в списке нет элемента, который не заканчивается на «x». Это, конечно, способ двойного отрицания сказать, что все элементы списка заканчиваются на «х».

Также обратите внимание, что фрагмент кода выдает:

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

Этот список содержит весь список, а не только элемент, который не заканчивается на «x».

Так есть ли идиоматический способ:

  • Утверждение, что каждый элемент заканчивается "x" (без двойных отрицаний)
  • В случае ошибки подтверждения перечислите только те элементы, которые не заканчиваются на "x"

Ответы [ 3 ]

23 голосов
/ 14 мая 2011

Вы ищете 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"
17 голосов
/ 14 мая 2011

Сопоставление, данное Дэвидом Харкнессом, выдает приятное сообщение для ожидаемой части . Однако сообщение для фактической части также определяется тем, какой метод 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) производит вывод, заданный Дэвидом:

  • С устройством сопоставления 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 голосов
/ 29 апреля 2015

Я знаю, что этот вопрос довольно старый, но сегодня, с Java 8, я бы лучше написал его с лямбдами, например,

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

Вот почему.

...