Using Collections to Write Better JUnit Tests

Using Collections to Write Better JUnit Tests

In this post, I am going to show you how to use the Java Collections API to help you both randomize and sort data so that it is more easily testable. Testable code leads to code that is easier to maintain. This will improve the longevity of any project.

Recently, I implemented a sorting algorithm in my application. This was a critical component in my application. I found it appropriate to write JUnit tests to validate the business logic. I was very happy with my implementation. Therefore, I thought I would share it with the world. Enjoy!

Pro Tip

It may be a bad code smell if you cannot set up, identity, and verify expected results for a given method. This may imply that your code is not easily testable. This can lead to unmaintainable and erroneous code. More advanced examples may require additional mocking of dependencies. Higher-level code may benefit more from integration testing.

Implement Comparable

First, I write a class that implements the Comparable interface:

public class SortableObj implements Comparable<SortableObj> {
       @Override
    public int compareTo(SortableObj b) {
               // fancy sorting
         }
}

Setup / Test

Then, I setup a test with expected vs actual results. After my objects are composed properly, I call a method to test my setup:

    @Test
    public void firstSortScenario() {
                // setup test
        SortableObj first = new SortableObj();
        // do some decoration

        SortableObj second = new SortableObj();
        // do some decoration

        SortableObj third = new SortableObj();
        // do some decoration

        SortableObj fourth = new SortableObj();
        // do some decoration

        List<SortableObj> expected = Arrays.asList(first, second, third, fourth);

        List<SortableObj> actual = Arrays.asList(fourth, third, first, second);

                // test
        shuffleTest(expected, actual);
    }

Validate/Assert

Finally, I use the Collections API to shuffle the actual list, sort it, and assert that it is equal to the expected list. This should cover edge cases where the order of the list affects the integrity of the sort.

    private void shuffleTest(List<SortableObj> expected, List<SortableObj> actual) {
        for(int i=0;i<10;i++) {
            Collections.shuffle(actual);
            Collections.sort(actual);
            assertThat(actual).isEqualTo(expected);
        }
    }

Conclusion

This is the format I use for all my tests. I set up some data, call the method that is under test, and then validate expected vs actual results. You should be able to apply this methodology to all unit tests. Calling shuffle helped put me at ease that I did not miss any odd edge cases based on the order of the original list.

Resources:

Junit

Mockito

Did you find this article valuable?

Support Phillip Ninan by becoming a sponsor. Any amount is appreciated!