JUnit/TestNG tip: Diffing Lists

A little cheap and cheerful JUnit/TestNG tip…

Problem

You’ve got two lists that you want to compare using assertEquals(). But when the assertion fails, the error message kinda sucks.

java.lang.AssertionError: expected:<[Person{name=Joe,starsign=Virgo,sex=Male}, Person{name=Jaimie,starsign=Libra,sex=Female}, Per
son{name=Ewan,starsign=Capricorn,sex=Male}]> but was:<[Person{name=Joe,starsign=Virgo,sex=Male}, Person{name=Jaimie,starsign=Scor
pio,sex=Female}]>
    at org.junit.Assert.fail(Assert.java:74)
    at org.junit.Assert.failNotEquals(Assert.java:448)
    at org.junit.Assert.assertEquals(Assert.java:102)
    ...

It’s really tricky to see exactly where the differences are in the list.

Solution

Join both the lists into a string, delimited by newlines and assert that instead. That will force your IDE’s multiline differ to kick in.

junit diff

This relies on having a sensible toString() method on your list items.

If your IDE doesn’t do this, or you can’t run your tests from your IDE, you should really get that seen to.

Here’s a method to do it:

import static java.lang.String.join;

...

public static <T> void assertList(List<T> actual, T... expected) {
  assertEquals(join(expected, "\n"), join(actual, "\n"));
}

That’s all. Now get back to work.

Other languages

Same approach works for any other language used in JetBrains IDEs (Python, Ruby, JavaScript, etc).