Reasons why Hamcrest matchers are not so great for Java testing

Hamcrest matchers are great….. not!

 

When asked why use Hamcrest, developers usually site readability and ease of test writing among the most popular reasons for their choice. In this post, we will break down some of these reasons in order for you to make a better choice of frameworks. We will focus on Hamcrests use in the Java language.

 

While the choice of APIs is usually done for purely technical reasons, sometimes it is also done to for styling or personal preferences. Hamcrest is a testing API that is offers a wide variety of matchers which are used during test results verification.

 

Hamcrest matchers improves readability (not)

 

Arguably the most cited reason for using Hamcrest is because it improves readability. Or does it? Let us explore some example. First, an example in good old JUnit:

 

Object isNull = bla;
assertNotNull(isNull);

 

Let us compare this with an example written in Hamcrest.

 

Object isNull = bla;
assertThat(isNull, is(not(nullValue())));

 

As you can see, in the first example, from just reading the assert method name, we know what the assertion is all about. But in the Hamcrest example, you need to “assertThat”, my object “isNull”, “is” …. “not” … “nullValue”. Very readable huh… Lets check another example. Let us start with the JUnit example:

 

assertEquals(33+2 , 36 );

 

From the example, it is clear from the method name that we are testing for equality. Now to the Hamrest example:

 

assertThat(.....

 

Oh boy, here we go again. Assert that what?…

 

assertThat(33+2, ....

 

Assert that 32 + 2 … ?

 

assertThat(33+2 , is(....

 

is what? is what? ….. the suspense … its too much…..

 

assertThat(33+2 , is(equalTo(36)));

 

Finally!

 

a Hamcrest assertThat example
a typical Hamcrest assertThat statement

 

Hamcrest makes you spot mistakes sooner (not really)

 

Wrong. For example, the following code will be syntactically acceptable and the mistake can only be found during runtime.

 

	@Test
	public void testHamcrest(){
		assertThat(33+2 , is(equalTo("Some String")));
	}

 

What about that its more difficult to confuse the expected result and the actual result? Well, I will give it to Hamcrest, it is much more difficult to confuse the expected and actual results, but the benefit is very minute and it is still easy to make mistakes. For example, when writing an equality assertion with an error message:

 

assertThat("Is this the first comparison argument", "or this one?" , is(equalTo("Some String")));

 

Why Hamcrest and Java are not a good combination?

 

Using Hamcrest matchers or not comes down to the individual preference of each developer. But perhaps the weak point of using them in Java is that Java is not a logic programming language. It is a good idea to keep coding style consistent within the code of a programming language as consistency improves readability. This is because the reader will not have to change the way they read and interpret code in order to understand it. Trying to force elements of a different programming paradigm onto a programming language is like adding chicken soap to a cup of hot cocoa. Yes, it is useful and delicious, but it just does not belong there.

Reasons why Hamcrest matchers are not so great for Java testing
Scroll to top