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.
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).