Строгое совпадение в подголовнике?
Я пытаюсь использовать Hamcrest, но постоянно сталкиваюсь со следующим:
Устройства Hamcrest имеют короткое замыкание, например, если я напишу:
Assert.assertThat(list, everyItem(not(isIn(shouldNotBeInList))));
Сообщается только о первом неисправном элементе shouldNotBeInList. Я ожидаю, что тесты скажут мне как можно больше.
Могу ли я написать утверждения в Hamcrest, чтобы они хорошо отчитывались, чтобы сообщалось обо всех несоответствиях, или я должен создать свои собственные сопоставители или использовать другую библиотеку?
Пример вывода для
List<String> list = Arrays.asList("a", "b", "c");
List<String> shouldNotBeInList = Arrays.asList("c", "e", "a");
Обратите внимание, нет сообщения об ошибке для c
Expected: every item is not one of {"c", "e", "a"}
but: an item was "a"
2 ответа
Hamcrest немного сложнее, когда дело доходит до читаемых сообщений об ошибках. Некоторые сопоставители создают полезное сообщение со всеми ошибками, другие (чаще всего) сообщают только о первой ошибке.
Конечно, вы можете создать свой собственный механизм сопоставления с "лучшей" реализацией и хорошим сообщением об ошибке. Делать это на одном или двух матчах - это нормально, но это может закончиться повторной реализацией Hamcrest.
Если вам удобнее использовать другую библиотеку, взгляните на AssertJ. Утверждение
Assertions.assertThat(list).doesNotContainAnyElementsOf(shouldNotBeInList);
выдает это сообщение об ошибке:
Expecting
<["a", "b", "c"]>
not to contain
<["c", "e", "a"]>
but found
<["c", "a"]>
public static void main(String[] args) {
List<String> list = Arrays.asList("a", "b", "c");
List<String> shouldNotBeInList = Arrays.asList("c", "e", "a");
Assert.assertThat(list, everyFullCheck(not(isIn(shouldNotBeInList))));
}
public static class EveryFullCheck<T> extends TypeSafeDiagnosingMatcher<Iterable<T>> {
private final Matcher<? super T> matcher;
public EveryFullCheck(Matcher<? super T> matcher) {
this.matcher= matcher;
}
@Override
public boolean matchesSafely(Iterable<T> collection, Description mismatchDescription) {
boolean matches = true;
for (T t : collection) {
if (!matcher.matches(t)) {
if (!matches) {
mismatchDescription.appendText(", ");
}
mismatchDescription.appendText("an item ");
matcher.describeMismatch(t, mismatchDescription);
matches = false;
}
}
return matches;
}
@Override
public void describeTo(Description description) {
description.appendText("every item is ").appendDescriptionOf(matcher);
}
}
private static <U> EveryFullCheck<U> everyFullCheck(Matcher<? super U> matcher) {
return new EveryFullCheck<>(matcher);
}
}
Ожидаемый: каждый элемент не является одним из {"c", "e", "a"}, но: элемент был "a", элемент был "c"