为什么在junit中assertEquals和assertSame为两个实例同一个类返回相同的结果?

raw*_*ata 18 java junit assert equals

根据文件

assertEquals()断言两个对象是相等的.

assertSame()断言两个对象引用同一个对象.

所以我期待如果我有一个类似下面的课程

class SomeClass {}
Run Code Online (Sandbox Code Playgroud)

然后

SomeClass someClass1= new SomeClass();
SomeClass someClass2= new SomeClass();
assertSame(someClass1,someClass2); // fail
assertEquals(someClass1,someClass2); // fail
Run Code Online (Sandbox Code Playgroud)

assertEquals应该传递,assertSame应该失败,因为两个类的值相等但它们具有不同的引用位置.

由于我在两种情况下都失败了,那么我的问题是这两者之间有什么区别?

Ale*_* C. 27

由于您没有在类中重写equals,因此assertEquals行为与assertSame默认等于实现比较引用的行为相同.

150    public boolean equals(Object obj) {
151        return (this == obj);
152    }
Run Code Online (Sandbox Code Playgroud)

如果你提供一个愚蠢的等于:

class SomeClass {
    @Override 
    public boolean equals(Object o) {
        return true;
    }
}
Run Code Online (Sandbox Code Playgroud)

你会看到assertEquals成功.


mkr*_*hin 11

assertEquals使用equals()方法(您应该在类中重写以真正比较其实例)来比较对象,同时assertSame使用==运算符来比较它们.因此差异与两者之间的差异==(按值比较)和equals(比较身份)完全相同.


Key*_*r00 8

官方 JUnit 文档:

assertEquals:断言两个对象相等

assertSame:断言两个对象引用同一个对象

换句话说

assertEquals:使用 equals() 方法,或者如果没有覆盖 equals() 方法,则比较 2 个对象之间的引用。

assertSame:比较两个对象之间的引用。

示例 1:equals 方法未被覆盖,因此 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>
    }
}
Run Code Online (Sandbox Code Playgroud)

示例 2:equals 方法被覆盖,因此 assertSame 和 assertEquals 返回不同的结果,因为这次 assertEquals 将使用 equals 方法。

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
    }
}
Run Code Online (Sandbox Code Playgroud)