web-dev-qa-db-fra.com

Pourquoi assertEquals et assertSame in junit renvoient le même résultat pour deux instances de la même classe?

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? 

12
rawData

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.

20
Alexis C.

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é).

8
mkrakhin

_ {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
    }
}
2
KeyMaker00

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.

0
Boris Pavlović