javajunitjunit4junit3

Assert.assertEquals on two lists


I have a class MySchool:

public class MySchool{
    private long timestamp;
    private SchoolEvent event;
    private Object value;

    //getter & setters
    ...

    @Override
    public String toString() {
        return "MySchool [timestamp=" + timestamp + ", event="
                + event + ", value=" + value + "]";
    }
}

SchoolEvent is an enum type:

public static enum SchoolEvent {
        CEREMONY, HOLIDAY
    }

I try to use Assert.assertEquals() to compare two List of schools :

List<MySchool> schoolList1 = generateSchools();
List<MySchool> schoolList2 = readSchoolsFromFile();

Assert.assertEquals(schoolList1, schoolList2);

It is failed with the following error:

expected: java.util.ArrayList<[MySchool [timestamp=0, event=CEREMONY, value=null], MySchool [timestamp=0, event=HOLIDAY, value=null]]> 

but was:  java.util.ArrayList<[MySchool [timestamp=0, event=CEREMONY, value=null], MySchool [timestamp=0, event=HOLIDAY, value=null]]>

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.

I also checked Java doc about List#equal , it also says :

two lists are defined to be equal if they contain the same elements in the same order.

Why the assertEquals() failed then?


Solution

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