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

Java 为什么junit中的assertEquals和assertSame对同一类的两个实例返回相同的结果?,java,junit,equals,assert,Java,Junit,Equals,Assert,根据文件 断言两个对象相等 assertSame()断言两个对象引用同一个对象 所以我希望如果我有一个像下面这样的课程 class SomeClass {} 然后 assertEquals应该通过,assertSame应该失败,因为两个类的值相等,但它们具有不同的引用位置 当我在这两种情况下都失败时,我的问题是这两者之间有什么区别?assertEquals使用equals()方法(您应该在类中重写该方法以真正比较其实例)来比较对象,而assertSame使用=操作符来比较它们。因此,差异与==

根据文件

断言两个对象相等

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

所以我希望如果我有一个像下面这样的课程

class SomeClass {}
然后

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


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

assertEquals
使用
equals()
方法(您应该在类中重写该方法以真正比较其实例)来比较对象,而
assertSame
使用
=
操作符来比较它们。因此,差异与
==
(按值比较)和
equals
(比较标识)之间的差异完全相同。

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

150    public boolean equals(Object obj) {
151        return (this == obj);
152    }
如果提供相等的哑重写:

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

您将看到
assertEquals
成功。

第一个断言失败,因为
someClass1
sameClass2
不是相同的实例。第二个断言失败,因为
equals(Object)
方法尚未在
SomeClass
中定义,其超级
equals(Object)
引用了相等。由于比较了两个不同的实例是否相等,因此此实例失败的原因与第一个相同。

JUnit官方文档:

断言相等:断言两个对象相等

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

换句话说

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

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>
    }
}
公共A类{
私人互联网i;
公共A(inti){this.i=i;}
}
公共类遗嘱{
最终A a1=新A(0);
最终A a2=新A(0);
@试验
公共无效资产相同_testAssertSame(){
assertSame(a1,a2);//断言错误:应为:但为:
}
@试验
公共无效资产相同_testAssertEquals(){
assertEquals(a1,a2);//断言错误:应为:但为:
}
}
示例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
    }
}
公共A类{
私人互联网i;
公共A(inti){this.i=i;}
@凌驾
公共布尔等于(对象o){
//自我检查
如果(this==o){return true;}else
//空检查
如果(o==null){return false;}else
//类型检查和类型转换
如果(getClass()!=o.getClass()){return false;}else{
最终A=(A)o;
//现场比较
返回对象。等于(a,a);
}
}
}
公共类遗嘱{
最终A a1=新A(0);
最终A a2=新A(0);
@试验
公共无效资产相同_testAssertSame(){
assertSame(a1,a2);//断言错误:应为:但为:
}
@试验
公共无效资产相同_testAssertEquals(){
assertEquals(a1,a2);//好的
}
}

资产质量:=
资产相同:==


“same”与类型以及与“==”相同的值相匹配。

assertEquals-它根据该类重写的equals()方法检查对象是否相等。因此,我们可以根据对象的状态检查对象的相等性(比较它们的实例变量的值)

assertEquals() assertEquals()方法使用两个对象的equals()方法比较它们是否相等

如果根据equals()方法的实现,这两个对象相等,则assertEquals()方法将正常返回。否则,assertEquals()方法将抛出异常,测试将在此停止

assertSame()和assertNotSame() assertSame()和assertNotSame()方法测试两个对象引用是否指向同一个对象。根据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
}

我不明白为什么我被否决了,因为这是一个准确的描述。请在否决投票前留下你的理由…我认为原因是你试图从javascript的角度解释,而有人不喜欢它,也不理解它。几乎任何语言都可以!不仅仅是JavaScript,这是java的问题。Java没有==。JavaScript已经成功了。
@Test
public void assertEquals_example() {
    Employee employeeNew = new Employee();
    employee.setSalary(1000000.0);
    assertEquals("EMPLOYEE OBJECT", employee, employeeNew);
}
@Test
public void assertSame_assertNoSame_example() {

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