I have a data source from which I can request a list of people that live in a (any) country, and a method which retrieves the people from that data source and sorts them by their name alphabetically. How should I write my unit test to make sure that the sorting part of my method works properly?
This is what my SUT looks like:
class PeopleStuff {
public IData data;
public List<Person> getSortedPeopleForCountry(String countryName) {
List<Person> people = data.getPeopleForCountry(countryName);
Comparator nameComparator = new PersonNameComparator();
Collections.sort(people, nameComparator);
return people;
}
}
And this is what my unit test looks like:
@Test public void testGetPeopleSortsByPeopleName() {
String COUNTRY = "Whatistan";
// set up test (the 3 lines below are actually in a @Before setup method)
PeopleStuff peopleStuff = new PeopleStuff();
IData mockData = createNiceMock(IData.class);
peopleStuff.data = mockData;
// set up data
List<PersonName> mockPeopleList = new ArrayList<PersonName>();
mockPeopleList.add(new Person(COUNTRY, "A"));
mockPeopleList.add(new Person(COUNTRY, "D"));
mockPeopleList.add(new Person(COUNTRY, "B"));
mockPeopleList.add(new Person(COUNTRY, "C"));
when(mockData.getPeopleForCountry(COUNTRY)).thenReturn(mockPeopleList);
// exercise
List<String> result = peopleStuff.getSortedPeopleForCountry(COUNTRY);
// assert
assertEquals("A", result.get(0).name);
assertEquals("B", result.get(1).name);
assertEquals("C", result.get(2).name);
assertEquals("D", result.get(3).name);
}
What I need to know is if the way I am stubbing the data, running the test and making the assertions is correct, or if there are better ways of doing this.
My application has a lot of methods to test and a lot of custom sorting algorithms; I implemented all tests to use some 4 values that I stub like that, in a "random" order which I choose when I write the test.
Should I just test if the comparators are called? That doesn't seem right to me, because I don't know if they're called for the right data or at the right time in the algorithm that's inside getSortedPeopleForCountry()
. I want to detect situations like this:
public List<Person> getSortedPeopleForCountry(String countryName) {
List<Person> people = data.getPeopleForCountry(countryName);
Comparator nameComparator = new PersonNameComparator();
List<Person> sortedPeople = new ArrayList<Person>(people)
Collections.sort(sortedPeople, nameComparator);
return people; // oops!
}
Should I leave it like this and add mock comparators which use the real comparators but also verify that they're being called?
Am I doing it right?