# 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](https://junit.org/junit5/) 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](https://site.mockito.org/)  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](https://junit.org/junit5/) 

 [Mockito](https://site.mockito.org/) 
