Why assertEquals and assertSame in junit return the same result for two instances same class?
Solution 1
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.
Solution 2
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).
Solution 3
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
}
}
Solution 4
assertEquals: ==
assertSame: ===
'same' matches the type along with the value which is the same as '==='.
rawData
Updated on May 11, 2020Comments
-
rawData almost 4 years
According to documentation
assertEquals() Asserts that two objects are equal.
assertSame() Asserts that two objects refer to the same object.
So I am expecting that if I have a class like below
class SomeClass {}
then
SomeClass someClass1= new SomeClass(); SomeClass someClass2= new SomeClass(); assertSame(someClass1,someClass2); // fail assertEquals(someClass1,someClass2); // fail
the assertEquals should pass and assertSame should fail, as the value of both classes are equal but they have different reference location.
As I get failure in both cases then my question is what are the difference between these two ?