Strange AllOf hamcrest matcher mismatch description

1.1k views Asked by At

I'm using hamcrest 1.3. Its implementation of matches(Object o, Description mismatch) looks like that:

@Override
public boolean matches(Object o, Description mismatch) {
    for (Matcher<? super T> matcher : matchers) {
        if (!matcher.matches(o)) {
            mismatch.appendDescriptionOf(matcher).appendText(" ");
            matcher.describeMismatch(o, mismatch);
          return false;
        }
    }
    return true;
}

When describing mismatch, it first appends the description of matcher that failed, and only then the actual mismatch. This results in some pretty odd message.

For example, if I write:

Description description = new StringDescription();
allOf(lessThan(2)).describeMismatch(5, description);
System.out.println(description.toString());

Then a value less than <2> <5> was greater than <2> is printed the console. I would expect just the <5> was greater than <2>, because that's the kind of message the other matchers return, e.g. lessThan used alone.

My question being: is this a bug or am I missing something?

The fact that different matchers return messages in different formats is a big deal, since I was trying to write some custom validation framework that uses the matchers and is able to return nice human readable messages if anything goes wrong. It seems that I can't use the describeMismatch method for that purpose...

1

There are 1 answers

0
ᴇʟᴇvᴀтᴇ On BEST ANSWER

I'd say it's a (usability) bug. The message could be more expressive simply with the word "but" instead of the space.

It's worth pointing out that the mismatch messages are normally displayed by JUnit's assertThat() with some additional words: "Expected" (shows the Matcher description), "Actual" (shows the mismatch). This makes it clearer.

Normally when you use an allOf() you'd have more than one matcher, so it's useful for the mismatch description to say which one broke. But I agree the message could be clearer.