Matchsticks4

© Image by Margarethe Pfründer-Sonn↗

In my previous blog post, I’ve written about the setup and the given part of a unit test.

This post is about the then part of the unit test.

These are the most common mistakes in the then part of a unit test:

bad assertions and good assertions

java’s assert keyword

Java’s↗ assert keyword only throws AssertionErrors when java was called with the -ae switch. If that switch was turned off, then assert does nothing.

So:

Do not use java’s assert keyword!

Confusing actual value and expected value

The old JUnit↗ library had an assertEquals method, where the expected value was the first parameter, and the actual value was the second parameter.

This is the opposite in spoken English or German language. For me, this has spoiled the assertEquals method forever.

So:

Do not use JUnit’s assertEquals!

Spock’s equals

Spock↗ has this feature:

In the then: part, it automatically evaluates every line as an expression. If the expression evaluates truthy, then the test will pass. If the expression evaluates falsy, then the test will fail.

So you can write

     then:
     actualValue == expectedValue

and spock will fail if the actualValue differs from the expectedValue.

but beware of:

     then:
     actualValue = expectedValue

This is no comparison but a variable assignment. It always evaluates to true, but you can hardly spot the difference!

I once even made an invalid test pass by accidentally comparing two thrown exceptions!

So if you want to use groovy’s↗ assert or spock’s evaluations in the then part:

Always, always use strictly TDD’s red-green, red-green style of coding.

Hamcrest matchers

I like reading hamcrest’s↗ assertions, because they are close to the natural English language and provide good error messages.

But writing them is a pain.

AssertJ

AssertJ↗ is my favourite. Reading the assertion statements is nice because they are close to the natural English language, just like Hamcrest. But the best thing: AssertJ has a nice fluent API, so writing assertions is easy: Just use your IDE’s autocomplete features. Additionally, AssertJ has nice assertions for collections.

Too many assertions

Sometimes I’ve seen test method with more than 10 assertions. When reading this, you can not see the forest for the trees. What is the business rule’s intention?

One assertion per test method!?

Maybe you can split the test. You then have two test methods, that share the same given and when part, but the then part is different.

Clean code cheat sheet↗ says:

Only one assertion for one test method.

In my opinion this is sometimes a bit too strict, but the intention is good.

Overspecification

Sometimes some aspects of the business rules we are implementing are not defined by the business experts. Often we developers fill the gaps with good intentions. But sometimes we are on the wrong track. We write unit tests for things, that we think make sense, but in reality this was not defined by the business.

Maybe later we learn that things should be different. Then we want to change the implementation code. But then we will find an existing unit test testing for a different behaviour.

Is that unit test for real or is it just a “developer that filled the gap with good intentions”?

So: If you have the feeling, that you code a test “with good intentions”:

  • Add some comments to make this visible.
  • Add some comments like: “this bad thing will happen if you remove/change this test” or “when removing/changing this test, please consider/think about…”

Debatable opinion: Maybe it’s better to not write this test!

This blog post was the last one for the setup - given - when - then pattern.

Next post is the first of a series on writing fast tests.

Any comments or suggestions? Leave an issue or a pull request!