When you write your unit tests you must use some kind of assertions. I think that most of you will agree with me on that the asserts that comes with the JUnit aren’t the easiest and most readable ones.
So, some time ago I started to use a Hamcrest matcher library. It was a great progress, as I was able to move away
from JUnit’s unintuitive: assertEquals(11.0, actual)
. I mean, if you try to read it out loud it doesn’t seem very logical:
“assert equals 11 is actual
”,
“assert equals 11 as actual
”?.
Moreover, the expected
value is the first argument and the actual
one is the latter which also makes it harder to understand.
And here comes the Hamcrest
matcher which brings a fluent API consisting of a lot of useful methods.
So, right now you can write: assertThat(actual, is(11.0))
. This is much more readable as it stands for:
“Assert that actual
is 11.0”.
No magic here, everything is understandable and you don’t have to think which parameter is the expected
and which is the actual
one.
FEST Fluent Assertions brings very similar features to the table but it takes quite different approach.
In Hamcrest you usually use the one-line per one assert approach. It means that if you want to check if myVal
is in
range between 4 and 6, you would need to write two assertions (sure, you can always write your own matcher that will do
it in one line, but that’s not the point in this case):
assertThat(myVal, is(greaterThan(4));
assertThat(myVal, is(lessThan(6));
FEST Fluent Assertions uses the chain method invocation to do the same thing, so in FEST-like approach you’d rather write:
assertThat(myVal).isGreaterThan(4).isLessThan(6);
You can still read it very naturally and it saved some writing.
There are some more differences between Hamcrest and FEST Fluent Assertions. Some of them are more important, like
differences in writing your own matchers and/or conditions.
Others are less important, like the number of static imports: lots in Hamcrest, only one in FEST Fluent Assertions.
However, this Hamcrest’s disadvantage, can be easily solved using type import static or using the Eclipse
support as described in my previous post
There is no, obvious choice between Hamcrest and FEST Fluent Assertions. Both of them give you a very nice and elastic fluent assertions mechanism and which one you choose depends on team, your programming habits or some particular requirements. Either it will be Hamcrest or FEST Fluent Assertions, it will definitely be better than the assertions that come out-of-the-box with JUnit.
I think that the most important fact here is that you really should use easy to read matchers library. It makes not only the code more obvious for your team, easier to maintain (it’s worth emphasizing that your test code is also a part of your project – it needs to be maintained!) but in some situations it even allows you to show some test cases to the business people with the domain knowledge you need. It allows to reduce domain understanding problems.
Moving even further, if you plan to use Scala (or any other JVM language which allows you to omit spaces or parentheses in method invocations), your code can be much more like a DSL (Domain Specific Language):
assertThat actual isEqualTo 11.0
It’s really worth trying it out.
You can read about differences between Hamcrest and FEST Fluent Assertions in more details on Sam Lewis’ blog.