Assert Equals Between 2 Lists in Junit

Assert.assertEquals on two lists

I don't understand why the error doesn't sound like an error, I mean just check the error message, every field of every element object in two lists are euqal.

Yes, but that doesn't mean that the objects are considered to be equal.

You need to override equals() (and hashCode()) in order for distinct objects to be considered equal. By default, the equals method just checks for object identity... in other words, x.equals(y) is equivalent to checking that x and y refer to the exact same object by default. If you want different behaviour - so that it checks for certain fields being equal - then you need to specify that behaviour in equals(), and implement hashCode() in a fashion consistent with that.

Note that this problem doesn't depend on collections at all. You'll get the same problem if you compare individual objects:

MySchool school1 = schoolList1.get(0);
MySchool school2 = schoolList2.get(0);
Assert.areEqual(school1, school2); // This will fail...

Assert equals 2 lists

Seeing your code, you add a new Employee in your expectedList giving that object a unique reference. The actual list will have another instance of Employee with another unique reference making these two different objects.

Although the two objects have the same fields, the assertEquals for list will use the equals method within Employee to check if the objects are the same. If you haven't implemented the equals method yourself inside Employee it will check on those unique references I mentioned before.

A solution would be to override the equals method in Employee like this:

@Override
public boolean equals(Object obj) {
if(!obj instanceof Employee) {
return false;
}
Employee e = (Employee) obj;
// Add more fields to compare if necessary
return this.getEmployeeId().equals(e.getEmployeeId()) && this.getAge().equals(e.getAge());
}

which should give you the results you're hoping for. Possible similar issue and probably better explanation.

As mentioned by @Zabuza you also need to override hashCode as well in case you use something like a HashMap in combination with Employee. Further explanation about `hashCode can be found here.

How to compare two List with JUnit

First, your problem is really not specific to java 8 Streams as
here you want to compare the Lists collected by the Streams and not the Streams themselves.

The both actual and expected results look like same but the test is
still failing.

Indeed they look like to have the same "content" but in fact they don't as in your test code you don't assert that two Strings are equal but you assert that a List<String> is equal to a List<DayOfWeek>.

The user friendly message associated to the test failure is just a textual representation of the compared objects.

Assert.assertEquals(Object, Object) invokes the equals() method on the first argument to determinate whether the two objects are equal :

public class Assert {
...
private static boolean isEquals(Object expected, Object actual) {
return expected.equals(actual);
}
...
}

And a DayOfWeek object whatever its toString() value is very probably not equal in terms of equals() method to a String object that has the same String content.

So, you have to use the same type of element in the Lists in the expected and the actual to make assertEqual() successful.

How to JUnit test that two ListE contain the same elements in the same order?

I prefer using Hamcrest because it gives much better output in case of a failure

Assert.assertThat(listUnderTest, 
IsIterableContainingInOrder.contains(expectedList.toArray()));

Instead of reporting

expected true, got false

it will report

expected List containing "1, 2, 3, ..." got list containing "4, 6, 2, ..."

IsIterableContainingInOrder.contain

Hamcrest

According to the Javadoc:

Creates a matcher for Iterables that matches when a single pass over the examined Iterable yields a series of items, each logically equal to the corresponding item in the specified items. For a positive match, the examined iterable must be of the same length as the number of specified items

So the listUnderTest must have the same number of elements and each element must match the expected values in order.

How to write a JUnit test to compare the equality of 2 lists of objects?

You are most likely missing correct hashCode() and equals() in the Position class. You need a test like:

Position a = new Position(1d, 1d);
Position b = new Position(1d, 1d);
assertThat(a).isEqualTo(b);

Your assumption about the assertions is incorrect, your test is not comparing using references. In AssertJ the isEqualTo() method in:

assertThat(deserializedPositionList).isEqualTo(positionList);

Verifies that the actual value is equal to the given one.

which is performed by calling the ArrayList.equals() method under the hood. To compare the lists by their reference one uses isSameAs():

assertThat(deserializedPositionList).isSameAs(positionList);

Verifies that the actual value is the same as the given one, ie using == comparison

which is performing the check with == operator as in deserializedPositionList == positionList.

AssertEquals 2 Lists ignore order

As you mention that you use Hamcrest,

So I would pick one of the collection Matchers

import static org.hamcrest.collection.IsIterableContainingInAnyOrder.containsInAnyOrder;
import static org.junit.Assert.assertThat;

public class CompareListTest {

@Test
public void compareList() {
List<String> expected = Arrays.asList("String A", "String B");
List<String> actual = Arrays.asList("String B", "String A");

assertThat("List equality without order",
actual, containsInAnyOrder(expected.toArray()));
}

}

Compare 2 ListString if they contain same elements in any order [JUnit - Asset]

You can first sort both the List and then compare the sorted Lists.

List<String> list1 = Arrays.asList("a","b","c");
List<String> list2 = Arrays.asList("c","a","b",);
Collections.sort(list1);
Collections.sort(list2);
assertEquals( list1, list2 ); // true


Related Topics



Leave a reply



Submit