web-dev-qa-db-ja.com

junitのassertEqualsとassertSameが同じクラスの2つのインスタンスに対して同じ結果を返すのはなぜですか?

ドキュメントによると

assertEquals()2つのオブジェクトが等しいことを表明します。

assertSame()2つのオブジェクトが同じオブジェクトを参照することをアサートします。

だから私は次のようなクラスがあると期待しています

class SomeClass {}

それから

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

assertEqualsは成功し、assertSameは失敗します。両方のクラスの値は等しいが、参照場所が異なるためです。

両方のケースで失敗した場合、私の質問はこれら2つの違いは何ですか?

17
rawData

クラスでequalsをオーバーライドしなかったため、assertEqualsassertSameと同じように動作します。これは、デフォルトが実装比較参照に等しいためです。

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

同等のバカなオーバーライドを提供する場合:

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

assertEqualsが成功することがわかります。

26
Alexis C.

assertEqualsequals()メソッド(実際にインスタンスを比較するためにクラスでオーバーライドする必要があります)を使用してオブジェクトを比較しますが、assertSame==演算子でそれらを比較します。したがって、違いは==(値による比較)およびequals(IDの比較)。

11
mkrakhin

公式のJUnitドキュメント:

assertEquals:2つのオブジェクトが等しいであることを表明します。

assertSame:2つのオブジェクトが同じオブジェクトを参照していることを表明します。

言い換えると

assertEquals:equals()メソッドを使用するか、equals()メソッドがオーバーライドされなかった場合、2つのオブジェクト間の参照を比較します。

assertSame:2つのオブジェクト間の参照を比較します。

例1:equalsメソッドはnotオーバーライドされたため、assertSameとassertEqualsはオブジェクトの参照を比較するため、同じ結果を返します。

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>
    }
}

例2:equalsメソッドがオーバーライドされたため、今度はassertEqualsによってequalsメソッドが使用されるため、assertSameとassertEqualsは同じ結果を返しません。

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
    }
}
4
KeyMaker00

assertEquals:==
assertSame:===

「同じ」は、「===」と同じ値を持つタイプと一致します。

0
tfont

assertEquals-そのクラスのオーバーライドされたequals()メソッドに基づいて、オブジェクトが等しいかどうかをチェックします。そのため、オブジェクトの状態に基づいてオブジェクトの等価性を確認できます(インスタンス変数の値を比較します)。

assertEquals()assertEquals()メソッドは、equals()メソッドを使用して、2つのオブジェクトが等しいかどうかを比較します。

@Test
public void assertEquals_example() {
    Employee employeeNew = new Employee();
    employee.setSalary(1000000.0);
    assertEquals("EMPLOYEE OBJECT", employee, employeeNew);
}

Equals()メソッドの実装に従って2つのオブジェクトが等しい場合、assertEquals()メソッドは正常に戻ります。そうでない場合、assertEquals()メソッドは例外をスローし、テストはそこで停止します。

assertSame()and assertNotSame() assertSame()およびassertNotSame()メソッドは、2つのオブジェクト参照が同じオブジェクトを指しているかどうかをテストします。指している2つのオブジェクトが、equals()メソッドに従って等しいことだけでは不十分です。指すオブジェクトとまったく同じでなければなりません。

以下に簡単な例を示します。

@Test
public void assertSame_assertNoSame_example() {

    assertSame(employeeService.getEmployeeFromId(1), employeeService.getEmployeeFromId(1));
    assertNotSame(employee, employeeService.getEmployeeFromId(1)); // We will get null as response
}
0
Saurabh Oza

_someClass1_と_sameClass2_は同じインスタンスではないため、最初のアサートは失敗します。 2番目のアサートは、equals(Object)メソッドがSomeClassで定義されておらず、そのスーパーequals(Object)が参照平等であるため失敗します。 2つの異なるインスタンスが等しいかどうか比較されるため、このインスタンスは最初と同じ理由で失敗します。

0
Boris Pavlović