Why assertEquals and assertSame in junit return the same result for two instances same class?
Since you didn't override equals in your class, assertEquals
behaves the same as assertSame
since the default equals implementation compare references.
150 public boolean equals(Object obj) {
151 return (this == obj);
152 }
If you provide a dumb overriding of equals:
class SomeClass {
@Override
public boolean equals(Object o) {
return true;
}
}
you'll see that assertEquals
succeeds.
assertEquals
uses equals()
method (that you should override in your class to really compare its instances) to compare objects, while assertSame
uses ==
operator to compare them. So the difference is exactly the same as between ==
(compare by value) and equals
(compare identity).
Official JUnit documentation:
assertEquals: Asserts that two objects are equal.
assertSame: Asserts that two objects refer to the same object.
In other words
assertEquals: uses the equals() method, or if no equals() method was overridden, compares the reference between the 2 objects.
assertSame: compares the reference between the 2 objects.
Example 1: equals method was not overridden, so assertSame and assertEquals return the same result, since they compare the objects' reference.
public class A {
private int i;
public A(int i){ this.i = i; }
}
public class TestA {
final A a1 = new A(0);
final A a2 = new A(0);
@Test
public void assertsame_testAssertSame(){
assertSame(a1, a2); // AssertionError: expected:<test2.A@7f13d6e> but was:<test2.A@51cdd8a>
}
@Test
public void assertsame_testAssertEquals(){
assertEquals(a1, a2); // AssertionError: expected:<test2.A@7f13d6e> but was:<test2.A@51cdd8a>
}
}
Example 2: equals method was overridden, so assertSame and assertEquals return the not same result, since the equals method will be used by assertEquals this time.
public class A {
private int i;
public A(int i){ this.i = i; }
@Override
public boolean equals(Object o){
// self check
if(this == o){ return true; } else
// null check
if(o == null){ return false;} else
// type check and cast
if(getClass() != o.getClass()){ return false; } else {
final A a = (A) o;
// field comparison
return Objects.equals(a, a);
}
}
}
public class TestA {
final A a1 = new A(0);
final A a2 = new A(0);
@Test
public void assertsame_testAssertSame(){
assertSame(a1, a2); // AssertionError: expected:<test2.A@7f13d6e> but was:<test2.A@51cdd8a>
}
@Test
public void assertsame_testAssertEquals(){
assertEquals(a1, a2); // OK
}
}