Sunday, November 24, 2013

JUnit asserts and assertThat

Keeping it simple

Now let's be honest, how many of us enjoy writing tests?  They are pretty tedious, even if some of the results are a bit of a surprise!  After all, the last thing we want is for writing tests to be a challenge - as soon as that happens, the test code is likely to need as much debugging as the code under test.

So the simpler it is to write clear tests the better ...

The path to fluency

Like most developers, I started off using JUnit's Assert methods ... assertEquals, assertTrue etc.  I went to TestNG for a while, and frequently got the expected and actual values the wrong way round.

A while ago, I found Fest "fluent" assertions, then at version 1.4.  I was much happier with that, and found that the claim to fluency was generally valid, and certainly led to more meaningful test failure messages.

But 1.4 was being retired, and 2.0 under development.  I tried early versions of 2.0 and there seemed to be some issues with type recognition, requiring some odd casting.  To be fair, these were milestone versions of Fest and these issues may have been fixed before 2.0 was released.

In the meantime I stumbled across the native JUnit assertThat() method, with Hamcrest matchers, being shipped with JUnit.  I hadn't noticed when this was first released, but I thought it may be a good time to migrate back to native JUnit.

Er, no. It wasn't.  Although the intent of JUnit assertThat() is similar to Fest, I quickly found that I was getting tangled up with the syntax, even allowing time for changing away from Fest.  I then found AssertJ, a fork from Fest 2.0 which seems to be more open to extending what can be "asserted".  So that's where I've ended up, and I am back to being nearly fluent again.

So what's the difference?

It's actually quite hard to quantify why I prefer AssertJ/Fest 2.0, except that it feels more natural - and it does seem that IDE auto-complete gets better results.  This is all purely subjective, and you may find it otherwise.

Fest 2.0 is practically identical in use to AssertJ, but AssertJ seems to be more open to extending the library... and let's face it there are plenty of things to test. 

Having said that, I am certain that all the assertThat() implementations (AssertJ, Fest, Hamcrest) are far more readable (and writeable)  than the original JUnit  Assert statements and all can be extended with custom matchers.

So if you want get more out of writing tests, I'd recommend giving AssertJ a try ... and if you are still using assertEquals, definitely give at least one of the assertThat() implementations a try.