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

时间:2015-02-11 10:26:07

标签: java junit equals assert

根据文件

  

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

     

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

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

class SomeClass {}

然后

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

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

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

6 个答案:

答案 0 :(得分:22)

由于您没有在类中重写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成功。

答案 1 :(得分:9)

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

答案 2 :(得分:2)

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

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

答案 3 :(得分:0)

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

答案 4 :(得分: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
}

答案 5 :(得分:-1)

assertEquals: ==
assertSame: ===

'same'与类型匹配,并与'==='相同。