Bad Tests Good Tests - Wasting Your Time

There are some things which are not worth unit-testing. Really, there are. Getters/setters and delegators are the best examples.

This post is a part of my new free book about tests. You can learn more here. Please share your comments (so the book is better).
The idea for the book is to discuss examples of test classes and to present ways of making them better.

Take for example this test (which, as all other tests in this book is real, however obfuscated).

@Test
public void shouldReturnImportantValue() {
    //given
    given(settings.getImportantValue())
        .willReturn(IMPORTANT_VALUE);

    //when
    BigDecimal importantValue
        = settingsFacade.getImportantValue();

    //then
    assertThat(importantValue)
        .isEqualByComparingTo(IMPORTANT_VALUE);
}

The test is about two classes - the SettingsFacade class which delegates calls to its collaborator of the Settings class. The tested method looks like this:

public BigDecimal getImportantValue() {
        return settings.getImportantValue();
}

Hm…. What kind of error do we expect to catch by writing this kind of tests?

I often hear that the real reason for writing such tests is because of the future evolution of code. Once upon a time a simple getter or delegator method will be updated and then we will find out whether its current functionality has been broken. I do not share this view. First of all it goes against the YAGNI principle. I can’t give precise numbers but I would say that the vast majority (99%?) of such simple methods will not evolve. Which means that 99 times of 100 you wasted your time writing tests. Second, any mature developer understands that when introducing some logic into existing method she/he needs to review the tests and update them. Third, there is a chance that even if your unit tests won’t notice the change, your higher level tests will.
Fourth, the hope that the future change of such method will be caught by our test is… well, it is only a hope. The thing is that you can not predict the future evolution of the code. What if the code evolves like this:

public BigDecimal getImportantValue() {
    return (settings.getImportantValue() != null)
        ? settings.getImportantValue() : DEFAULT_VALUE;
}

Our old test will still pass, won’t it? The thing is that it can prevent only some changes to the code.

So what should we do with the test in question. IMHO the best thing is not to waste time writing it.

Thing to remember: Test everything that can break. Do not waste your time testing what is "too simple to break".

Its not future evolution that

Its not future evolution that drives unit testing getters/setters - its the code coverage gap that will allow far more complex logic to lie uncovered. I have a getter/setter unit testing chunk of logic that covers all simple properties of an entire class with a single line of test code. A class with more complex getters/setters might be covered with 4-5 lines of code.

 
 
 
This used to be my blog. I moved to http://tomek.kaczanowscy.pl long time ago.

 
 
 

Please comment using