Java中的平等性测试

Java中的平等性测试,java,junit,Java,Junit,如何在Java中使用equals方法?在JUnit中,我通过断言两个初始化为相等的值是否相同来测试它们,但是我的测试失败了。我确保检查传入的对象是否是另一个对象的实例,但我不确定测试失败的原因 @Test public void testEqualityOnBillSimple() { Date d1 = new Date( 3,4,2020); Money m1 = new Money(10); Bill b1 = new Bill( m1, d1, "fred");

如何在Java中使用equals方法?在JUnit中,我通过断言两个初始化为相等的值是否相同来测试它们,但是我的测试失败了。我确保检查传入的对象是否是另一个对象的实例,但我不确定测试失败的原因

@Test
public void testEqualityOnBillSimple()
{
    Date d1 = new Date( 3,4,2020);
    Money m1 = new Money(10);
    Bill b1 = new Bill( m1, d1, "fred");
    Bill b2 = new Bill( m1, d1, "fred");

    assertTrue( b1.equals(b2));
}

public boolean equals (Object toCompare) {
    try {
        if (toCompare instanceof Bill) {
            Bill that = (Bill) toCompare;
            return this.amount.equals(that.amount) && 
            this.dueDate.equals(that.dueDate) && 
           this.paidDate.equals(that.paidDate) && 
            this.originator.equals(that.originator);
        }
    } catch (Exception e) {
    }
    return false;
}
如何在Java中使用equals方法

你叫它


你真正想知道的是为什么你的测试失败了。这就涉及到如何正确实现
equals(Object)
。一般来说,答案是它取决于(整个)对象的预期语义

表面上看,您编写的代码基本上是正确的。像您所做的那样捕获和挤压异常是一种不好的做法,而且可能在语义上不正确。它可能隐藏了你问题的真正原因;e、 g.一次现场比较中的意外NPE

你评论道:


我意识到这是有问题的,但它现在对我的代码有影响吗

有可能,是的

正确的行为是,
equals
可能会允许任何意外的未检查异常传播。比较缺少字段的不完整的
Bill
对象可以说是不正确的。如果代码旨在处理该问题(即
null
字段),则应使用
null
测试来避免NPE

(我认为将
null
字段视为导致
equals
返回
false
是没有意义的。例如,如果将
账单
null
字段本身进行比较,会怎么样。)

为了完全确保没有其他问题,我们需要查看
Bill
类的其余实现


最后,正如@a-sir所指出的,如果你覆盖
等于
,你也应该(技术上)覆盖
hashCode
。如果您将
账单
用作
HashMap
中的键或
HashSet
的元素,则会发生不好的事情。。。类具有不兼容的
equals
hashCode
方法

如何在Java中使用equals方法

你叫它


你真正想知道的是为什么你的测试失败了。这就涉及到如何正确实现
equals(Object)
。一般来说,答案是它取决于(整个)对象的预期语义

表面上看,您编写的代码基本上是正确的。像您所做的那样捕获和挤压异常是一种不好的做法,而且可能在语义上不正确。它可能隐藏了你问题的真正原因;e、 g.一次现场比较中的意外NPE

你评论道:


我意识到这是有问题的,但它现在对我的代码有影响吗

有可能,是的

正确的行为是,
equals
可能会允许任何意外的未检查异常传播。比较缺少字段的不完整的
Bill
对象可以说是不正确的。如果代码旨在处理该问题(即
null
字段),则应使用
null
测试来避免NPE

(我认为将
null
字段视为导致
equals
返回
false
是没有意义的。例如,如果将
账单
null
字段本身进行比较,会怎么样。)

为了完全确保没有其他问题,我们需要查看
Bill
类的其余实现



最后,正如@a-sir所指出的,如果你覆盖
等于
,你也应该(技术上)覆盖
hashCode
。如果您将
账单
用作
HashMap
中的键或
HashSet
的元素,则会发生不好的事情。。。类具有不兼容的
equals
hashCode
方法。

originator是表示账单支付给谁的字符串。在本例中,问题是您是否覆盖了
equals()
方法和
hashcode()
?对不起,我不熟悉hashcode。是的,您捕获了一个
异常
,吞下了它,但没有对它做任何处理。这是一个非常糟糕的做法,因为如果那里发生了错误,那么您不知道,它默认为
#equals
,神秘地返回false。我意识到这是有问题的,但它现在对我的代码有影响吗?这是我测试套件中一系列错误/失败的临时解决方案。originator是表示账单支付给谁的字符串。在本例中,问题是您是否覆盖了
equals()
方法和
hashcode()
?对不起,我不熟悉hashcode。是的,您捕获了一个
异常
,吞下了它,但没有对它做任何处理。这是一个非常糟糕的做法,因为如果那里发生了错误,那么您不知道,它默认为
#equals
,神秘地返回false。我意识到这是有问题的,但它现在对我的代码有影响吗?这是我测试套件中一系列错误/失败的临时解决方案。