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

问题描述 投票:12回答:6

根据文件

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

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

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

class SomeClass {}

然后

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

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

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

java junit equals assert
6个回答
24
投票

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

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

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

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

你会看到assertEquals成功了。


9
投票

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


2
投票

官方JUnit文档:

assertEquals:断言两个对象是相等的。

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

换一种说法

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

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

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

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

0
投票

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


0
投票

assertEquals:== assertSame:===

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


0
投票

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

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

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

如果两个对象根据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
}
© www.soinside.com 2019 - 2024. All rights reserved.