Strict matching in hamcrest?

£可爱£侵袭症+ 提交于 2019-12-11 01:47:43

问题


I'm trying to use Hamcrest, but constantly run into the following:

Hamcrest matchers are shortcircuited, so for eg if I write:

 Assert.assertThat(list, everyItem(not(isIn(shouldNotBeInList))));

Just the first faulty element of shouldNotBeInList is reported. I expect tests to tell me as much, as possible.

Could I write assertions in hamcrest, that they report nicely, so that all mismatches are reported, or should I create my own matchers or use another library?

Example output for

List<String> list = Arrays.asList("a", "b", "c");
List<String> shouldNotBeInList = Arrays.asList("c", "e", "a");

Notice no error message for c

Expected: every item is not one of {"c", "e", "a"}
     but: an item was "a"

回答1:


Hamcrest is a bit tricky when it comes to readable error messages. Some matchers create a helpful message with all errors, others (the most) report only the first error.

Of course you could create your own matcher with a "better" implementation and a good error message. Doing this for one or two matchers is okay, but this could end in reimplementing Hamcrest.

If using another library is an option for you, take a look at AssertJ. The assertion

Assertions.assertThat(list).doesNotContainAnyElementsOf(shouldNotBeInList);

gives this error message:

Expecting
 <["a", "b", "c"]>
not to contain
 <["c", "e", "a"]>
but found
 <["c", "a"]>



回答2:


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);
    }
        }

Expected: every item is not one of {"c", "e", "a"} but: an item was "a", an item was "c"



来源:https://stackoverflow.com/questions/40015862/strict-matching-in-hamcrest

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!