assertEquals(Object, Object)
from JUnit4/JUnit 5 or assertThat(actual, is(expected));
from Hamcrest proposed in the other answers will work only as both equals()
and toString()
are overrided for the classes (and deeply) of the compared objects.
It matters because the equality test in the assertion relies on equals()
and the test failure message relies on toString()
of the compared objects.
For built-in classes such as String
, Integer
and so for ... no problem as these override both equals()
and toString()
. So it is perfectly valid to assert List<String>
or List<Integer>
with assertEquals(Object,Object)
.
And about this matter : you have to override equals()
in a class because it makes sense in terms of object equality, not only to make assertions easier in a test with JUnit.
To make assertions easier you have other ways.
As a good practice I favor assertion/matcher libraries.
Here is a AssertJ solution.
org.assertj.core.api.ListAssert.containsExactly()
is what you need : it verifies that the actual group contains exactly the given values and nothing else, in order as stated in the javadoc.
Suppose a Foo
class where you add elements and where you can get that.
A unit test of Foo
that asserts that the two lists have the same content could look like :
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.Test;
@Test
void add() throws Exception {
Foo foo = new Foo();
foo.add("One", "Two", "Three");
Assertions.assertThat(foo.getElements())
.containsExactly("One", "Two", "Three");
}
A AssertJ good point is that declaring a List
as expected is needless : it makes the assertion straighter and the code more readable :
Assertions.assertThat(foo.getElements())
.containsExactly("One", "Two", "Three");
But Assertion/matcher libraries are a must because these will really further.
Suppose now that Foo
doesn't store String
s but Bar
s instances.
That is a very common need.
With AssertJ the assertion is still simple to write. Better you can assert that the list content are equal even if the class of the elements doesn't override equals()/hashCode()
while JUnit way requires that :
import org.assertj.core.api.Assertions;
import static org.assertj.core.groups.Tuple.tuple;
import org.junit.jupiter.api.Test;
@Test
void add() throws Exception {
Foo foo = new Foo();
foo.add(new Bar(1, "One"), new Bar(2, "Two"), new Bar(3, "Three"));
Assertions.assertThat(foo.getElements())
.extracting(Bar::getId, Bar::getName)
.containsExactly(tuple(1, "One"),
tuple(2, "Two"),
tuple(3, "Three"));
}