Selon la documentation
assertEquals () Assure que deux objets sont égaux.
assertSame () Affirme que deux objets font référence au même objet.
Je m'attends donc à ce que si j'ai un cours comme ci-dessous
class SomeClass {}
puis
SomeClass someClass1= new SomeClass();
SomeClass someClass2= new SomeClass();
assertSame(someClass1,someClass2); // fail
assertEquals(someClass1,someClass2); // fail
assertEquals doit réussir et assertSame doit échouer, car les valeurs des deux classes sont égales mais leur emplacement de référence est différent.
Comme je rencontre un échec dans les deux cas, ma question est la suivante: quelle est la différence entre ces deux cas?
Etant donné que vous n'avez pas substitué égal à égal à dans votre classe, assertEquals
se comporte de la même manière que assertSame
puisque la référence par défaut égale l'implémentation compare les références.
150 public boolean equals(Object obj) {
151 return (this == obj);
152 }
Si vous fournissez un dépassement muet d'égaux:
class SomeClass {
@Override
public boolean equals(Object o) {
return true;
}
}
vous verrez que assertEquals
réussit.
assertEquals
utilise la méthode equals()
(que vous devez remplacer dans votre classe pour vraiment comparer ses instances) pour comparer des objets, alors que assertSame
utilise l'opérateur ==
pour les comparer. Donc, la différence est exactement la même qu'entre ==
(comparer par valeur) et equals
(comparer identité).
_ {Documentation officielle de JUnit: _
assertEquals: affirme que deux objets sont égaux.
assertSame: affirme que deux objets font référence au même objet.
En d'autres termes
assertEquals: utilise la méthode equals () ou, si aucune méthode d'equals () n'a été remplacée, compare la référence entre les 2 objets.
assertSame: compare la référence entre les 2 objets.
Exemple 1: la méthode equals était pas remplacée, donc assertSame et assertEquals renvoient le même résultat, puisqu'elles comparent la référence des objets.
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>
}
}
Exemple 2: la méthode equals a été remplacée. AssertSame et assertEquals renvoient le même résultat, car la méthode equals sera utilisée par assertEquals cette fois.
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
}
}
La première assertion échoue car someClass1
et sameClass2
ne sont pas les mêmes instances. La deuxième assertion échoue car la méthode equals(Object)
n'a pas été définie dans SomeClass
et que sa super equals(Object)
fait référence à l'égalité. Etant donné que deux instances différentes sont comparées pour l'égalité, celle-ci échoue pour la même raison que la première.