4

I am currently writing a unit test that is checking if a method is correctly sorting a list.

The sorting method is overrding a compare method from the clas Comparator and is sorting the list using Collections.sort().

It may not be a technical question, but I am looking for a way to use JUnit's assertions to check if the list is correctly sorted...

The list is sorted by an inner parameter of the type it is holding, let me call it id. So when the list contains 3 items with ID's: 3,1,2 - it shall sort them as 1,2,3.

Long expected1 = listOfObjects.get(0).getId()
Long expected2 = listOfObjects.get(1).getId()
Long expected3 = listOfObjects.get(2).getId()

And then using asserions on those Long objects ain't looking clean nor clever. I am looking for an idea how to cleanly and cleverly test this case, but I'm out of ideas...

hc0re
  • 1,806
  • 2
  • 26
  • 61
  • Do you have to limit yourself to JUnit? You could use assertj to great effect here – fge Nov 12 '15 at 16:40
  • 1
    Possible duplicate of [How to check if collection contains items in given order using Hamcrest](http://stackoverflow.com/questions/15609132/how-to-check-if-collection-contains-items-in-given-order-using-hamcrest) – Michael Lloyd Lee mlk Nov 12 '15 at 16:43
  • 2
    Not exactly the question, but since Collections.sort() is used, wouldn't it be easier to simply test your comparator class? It has the logic on how you want to sort and it is probably easier to test (always same input etc), e.g. Assert.assertEquals(1, comparator.compare(1,2)) and so on – pandaadb Nov 12 '15 at 16:48
  • I agree that you should do most of your testing on the comparator. But the method that uses Collections.sort should be (lightly) tested, and for that `contains` will do the job. – Michael Lloyd Lee mlk Nov 12 '15 at 17:02

2 Answers2

5

IMO, you should just unit test the compare method your wrote. Collections.sort() has already been heavily tested!

Just have one simple final test to make sure that Collections.sort() is properly called by the method you wrote:

private final MyComparator comparator = new MyComparator();

@Test
public greaterTest() {
    MyObject o1 = new MyObject(2);
    MyObject o2 = new MyObject(1);
    int c = comparator.compare(o1, o2);
    // assert that c is > 0
}

@Test
public lowerTest() {
    MyObject o1 = new MyObject(1);
    MyObject o2 = new MyObject(2);
    int c = comparator.compare(o1, o2);
    // assert that c is < 0
}

@Test
public equalTest() {
    MyObject o1 = new MyObject(2);
    MyObject o2 = new MyObject(2);
    int c = comparator.compare(o1, o2);
    // assert that c is == 0
}

@Test
public sortTest() {
    List<MyObject> os = // ...
    // call to the function that makes the call to Collections.sort
    List<MyObject> expected = // sorted version of os
    // assert that the sorted list is equal to the expected one
}
Jean Logeart
  • 52,687
  • 11
  • 83
  • 118
1

Have a look on my presentation which contains a point about asserting on lists and shazamcrest library which solves the problem.

With it you can just do assertThat(actual, sameBeanAs(asList(a, b, c))), where a, b and c are your objects of any type.

Jaroslaw Pawlak
  • 5,538
  • 7
  • 30
  • 57
  • Why use shazzamcrest, Hamcrests `contains` already does this? – Michael Lloyd Lee mlk Nov 12 '15 at 16:46
  • If you want to assert on objects, they will need to have `equals` method (or you have to hold a reference to every object in the list). For `shazamcrest` it doesn't matter. Also, `sameBeanAs` throws `ComparisonFailure` so you get very good diagnostics. – Jaroslaw Pawlak Nov 12 '15 at 16:48