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:
Did you find this article valuable?
Support Phillip Ninan by becoming a sponsor. Any amount is appreciated!