What should be considered for unit-testing? Part 1

Generally, if you expect a self written method to do something -ANYTHING-, for you you have to test that expectation!

No need to mention that we won’t test getters and setters and these kinds of super intuitive stuff unless we are the only alive persons on the planet who are bored to death!

So, now that we stated a really fancy intellectual statement, it is time for some real-world examples:

I’m sure you can find tones of normal examples, so I decided to pick some special cases for this article, which developers are more likely to avoid.

  1. Interfaces that have default methods.
  2. Generic classes.
  3. Methods which are using other static methods.

1. Interfaces which has default methods

Let’s say we have a print interface that has two default methods and one abstract.

public interface Print {

    default void printHi() { System.out.println("hi"); }

    default void printBye() { System.out.println("bye");}

    void print(String message);
}

Referring to our fancy statement above, we expect whenever we call for, for example printHi(), the word “hi” to be printed in the console and after that a new line. So nothing stops us to write unit tests for it.

public class DefaultInterfaceTest { 
    // you could also instantiate it and leave the print method simply empty

    private final Print testedClass = System.out::println;
    private ByteArrayOutputStream standardTerminal;

    @Before
    public void setup() {
//you can get hold of the content which get reflected to standard terminal
        standardTerminal = new ByteArrayOutputStream();
        System.setOut(new PrintStream(standardTerminal));
    }

    @Test
    public void test_printHi() {
        testedClass.printHi();
        assertEquals("should print hi in terminal", "hi\n",    standardTerminal.toString());
    }

    @Test
    public void test_printByte() {
        testedClass.printBye();
        assertEquals("should print bye in terminal", "bye\n", standardTerminal.toString());
    }

Don’t forget to read the comment 🙂

Some more points worthy to mention are:

  • For print(String a), you shouldn’t test it in terms of DefaultInterface test class, because it’s an abstract method, and testing it, is a thing that we expect to happen from the class which implements it.
  • I have deliberately used print functionality to show you that this is not a good excuse to ignore testing a method just because it’s a void method or does nothing but print some message in the console. I tell you why; because one of the most important aspects of having good code coverage is to reduce the possibility of changing code by mistake, especially when we are working in a team.
  • If you override the default implementation don’t forget to test it!

Stay tuned for the next two coming parts.