'ArrayList equality in junit not working although expected and actual are similar

I am using below test method to check whether the Arraylist is sorted as expected.

  @Test
  void compareFields()
  {
    Assignment14 assignment14 = new Assignment14();

    ArrayList<Person> PeopleList = new ArrayList<Person>();
    PeopleList.add(new Person("Alex",56));
    PeopleList.add(new Person("Thomas",23));
    PeopleList.add(new Person("John",10));

    ArrayList<Person> actualSortedResult = assignment14.compareFields(PeopleList);

    ArrayList<Person> expectedSortedResult = new ArrayList<Person>();
    expectedSortedResult.add(new Person("Alex",56));
    expectedSortedResult.add(new Person("John",10));
    expectedSortedResult.add(new Person("Thomas",23));

    Assert.assertEquals(expectedSortedResult, actualSortedResult);
  }

But although the expected and the actual are similar an error is occuring as fellows.

java.lang.AssertionError: expected: java.util.ArrayList<[Person{name='Alex', age=56}, Person{name='John', age=10}, Person{name='Thomas', age=23}]> but was: java.util.ArrayList<[Person{name='Alex', age=56}, Person{name='John', age=10}, Person{name='Thomas', age=23}]>
Expected :java.util.ArrayList<[Person{name='Alex', age=56}, Person{name='John', age=10}, Person{name='Thomas', age=23}]> 
Actual   :java.util.ArrayList<[Person{name='Alex', age=56}, Person{name='John', age=10}, Person{name='Thomas', age=23}]>
<Click to see difference>

I have tried the below assertion types but nothing worked.

   assertTrue("check equality", Arrays.equals(expectedSortedResult.toArray(), actualSortedResult.toArray()));
   Assert.assertEquals(expectedSortedResult, actualSortedResult);
   assertEquals(expectedSortedResult, actualSortedResult);
   assertTrue(expectedSortedResult.equals(actualSortedResult));
   assertArrayEquals(expectedSortedResult, actualSortedResult);

Can I know what is wrong with my method or what should be done?



Solution 1:[1]

ArrayList equals contract said this : Returns true if and only if the specified object is also a list, both lists have the same size, and all corresponding pairs of elements in the two lists are equal.

So looking at your error you have to check the equals contract of Person type. If you don't override the equals for this type the references are compare and so your lists are not equals

So you have to override equals method based on name and age fields to solve your problem.

Solution 2:[2]

A quick and easy way: just simply add @EqualsAndHashCode on your Person class. @EqualsAndHashCode is provided by Project Lombok and generates hashCode and equals implementations from the fields of your object.

@EqualsAndHashCode
public class Person {
   private String name;
   private int age;
   // ...
}

And the following assertion works well in JUnit4

Assert.assertEquals(expectedSortedResult, actualSortedResult);

https://projectlombok.org/features/EqualsAndHashCode

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 CodeScale
Solution 2 Kai-Sheng Yang