2015-02-11 14 views
6

Według dokumentacjiDlaczego assertEquals i assertSame w jednostce junit zwracają ten sam wynik dla dwóch wystąpień tej samej klasy?

assertEquals() twierdzi, że dwa obiekty są równe.

assertSame() Zapewnia, że ​​dwa obiekty odnoszą się do tego samego obiektu.

Więc ja oczekuję, że jeśli mam klasy jak poniżej

class SomeClass {} 

następnie

SomeClass someClass1= new SomeClass(); 
SomeClass someClass2= new SomeClass(); 
assertSame(someClass1,someClass2); // fail 
assertEquals(someClass1,someClass2); // fail 

się assertEquals przejść i assertSame niepowodzeniem. ponieważ wartość obu klas jest równa, ale mają one inną lokalizację odniesienia.

Ponieważ w obu przypadkach otrzymuję błąd, moje pytanie brzmi: jaka jest różnica między tymi dwoma?

Odpowiedz

10

Ponieważ nie zastąpiłeś równych w klasie, assertEquals zachowuje się tak samo, jak assertSame, ponieważ domyślnie jest równa referencji implementacji.

150 public boolean equals(Object obj) { 
151  return (this == obj); 
152 } 

Jeśli podasz niemego nadrzędnych wynosi:

class SomeClass { 
    @Override 
    public boolean equals(Object o) { 
     return true; 
    } 
} 

zobaczysz, że assertEquals powiedzie.

7

assertEquals wykorzystuje equals() metody (które powinny zastąpić w swojej klasie naprawdę porównać jego instancje), aby porównać przedmiotów, natomiast assertSame== operator wykorzystuje je porównać. Tak więc różnica jest dokładnie taka sama jak pomiędzy == (porównaj według wartości) i equals (porównaj tożsamość).

0

Pierwsza assert nie powiedzie się, ponieważ someClass1 i sameClass2 nie są tymi samymi instancjami. Drugie twierdzenie kończy się niepowodzeniem, ponieważ metoda equals(Object) nie została zdefiniowana w SomeClass, a jej super equals(Object) ma odniesienie równości. Ponieważ porównuje się dwie różne instancje dla równości, ta jedna kończy się niepowodzeniem z tego samego powodu, co pierwsza.

2

Oficjalna dokumentacja JUnit:

assertEquals: twierdzi, że dwa obiekty są równe .

assertSame: Zapewnia, że ​​dwa obiekty odnoszą się do tego samego obiektu .

Innymi słowy

assertEquals: wykorzystuje równych() sposobu, lub jeśli nie ma sobie równych() Metoda ta została zastąpiona, porównuje stosunek między 2 obiektów.

assertSame: porównuje odniesienie między 2 obiektami.

Przykład 1: metoda była równa nie zastępowane, tak assertSame i assertEquals zwrócić ten sam efekt, ponieważ porównaj odniesienie obiektów.

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:<[email protected]> but was:<[email protected]> 
    } 

    @Test 
    public void assertsame_testAssertEquals(){ 
     assertEquals(a1, a2); // AssertionError: expected:<[email protected]> but was:<[email protected]> 
    } 
} 

Przykład 2: odpowiada metoda została zastąpiona tak assertSame i assertEquals zwrócić nie taki sam wynik, ponieważ metoda równe będą wykorzystane przez assertEquals tego czasu.

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:<[email protected]> but was:<[email protected]> 
    } 

    @Test 
    public void assertsame_testAssertEquals(){ 
     assertEquals(a1, a2); // OK 
    } 
}