Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can the output of the "but: was" clause be customised?

Tags:

hamcrest

I am trying to write a custom matcher that navigates deep down the object graph to check an important property.

assertThat( writeRequest, hasRole("admin") );

When this fails I'd like to see a message like:

Expected: "admin"
     but: was "read-only"

However, when the assertion fails, it prints out the toString() on the writeRequest which means that the information I want would be deep in the string. To make matters worse, along the object graph is a generated class which does not @Override Object.toString() so that you cannot even find out (without logging or breakpoints) what the actual role the user had was!

So, in Hamcrest, is there any way to customize the output that appears in the but: was clause?

like image 986
Sled Avatar asked Aug 09 '14 18:08

Sled


1 Answers

tl;dr: override org.hamcrest.BaseMatcher.describeMismatch(Object item, Description description)


While running a test using org.hamcrest.collection.IsIterableWithSize I spotted a test failure with the message:

Expected: an iterable with size <1>
     but: iterable size was <0>

which has a customised but clause!

Looking into source code for IterableWithSize I notice that the string "iterable size" is being passed into org.hamcrest.FeatureTypeMatcher as the parameter featureName. Traced this up through org.hamcrest.TypeSafeDiagnosingMatcher where I spotted the describeMismatch(Object,Description) method. Since BaseMatcher has an implementation of that method, if you get the IDE to generate stubs of missing methods you'll miss it.

like image 177
Sled Avatar answered Sep 28 '22 00:09

Sled