Test Driven Development Fixtures

We all tend to write helper classes for testing, which clutters the test code and makes it harder to understand. A test should be like a story that you simply can read from top-down. I like test story better than fixture and I will use story and fixture interchangeable.

Why a Story Is More Powerful Than a Helper

If you have helpers you have code somewhere else, most often at the end of the test or even in another class where you hold all these helper utilities. If I read a test and I see method calls I tend to think that this is the code I test, but it is not. Helper utilities are also a sign that you probably need these utils also in your code and you should have tests for these utilities. As well helpers break the flow of your test story, it is like a reference to another story which you also should read before you can go on with this story. How awkward would that be in a book? Well, it is awkward as well in tests.
Unfortunately, this is hard to teach and to make visible why helper utilities are not a good thing.
When I write a test, I start with one single test and pack everything in that test I need, like calling methods, filling in entities, whatever is needed. Then I write a second test and do the same and after the third test, I put all the similarities into the setup method which is called before every test. And this holds the story. In Java JUnit5 it is the @BeforeEach annotation.

Let's Jump Into The First Story

We base this blog article on the Test Driven Development Mantra. If not done yet read that first as it will give you a better understanding of the test refactoring we are going to make now.

We have two tests from that article (and maybe you did the exercise and wrote the next test with for "good afternoon")

  @Mock
    private DateTime dateTime

@Test
    void shouldSayGoodMorningToTom() {
        when(dateTime.getHourOfDay()).thenReturn(6);
        assertEquals("Good morning Tom", sayHelloTo("Tom", new DateTime()));
    }

   @Test
    void shouldSayGoodMorningToJerry() {
        when(dateTime.getHourOfDay().thenReturn(6);
        assertEquals("Good morning Jerry", sayHelloTo("Jerry", new DateTime()));
    }

The similarities are very obvious here and you can make a good morning fixture out of it like this

public class GoodMorningTest {
    @Mock
    DateTime dateTime;

    @BeforeEach
    void setUp() {
        when(dateTime.getHourOfDay().thenReturn(6);
    }

@Test
    void shouldSayGoodMorningToTom() {
        assertEquals("Good morning Tom", sayHelloTo("Tom", new DateTime()));
    }

   @Test
    void shouldSayGoodMorningToJerry() {
        assertEquals("Good morning Jerry", sayHelloTo("Jerry", new DateTime()));
    }
}

That's it. You can read it top-down without any distractions. You have all together which makes tests very easy to read. Avoid helpers at all cost, it asks for troubles and confused programmers. And I'm well aware that this here is a very simple example, but honestly, most often it is not much more complicated than this here, test driven development favors simplicity.

Let me know if you have suggestions or questions in the comments below.

Christian Liesch

Software Developer

Leave a Reply

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.