【问题标题】:Technique to automatically check consistency of equals, hashCode, and compareTo?自动检查equals、hashCode和compareTo一致性的技术?
【发布时间】:2012-03-26 07:30:27
【问题描述】:

我很清楚合同需要确保hashCodeequals 一致并且equalscompareTo 一致。但是,这是often violated in practice。是否有任何工具、技术或库可以自动测试这种一致性?

不幸的是,我怀疑答案是否定的,但是如果能够对这种可以利用库调用或框架而不需要编写自定义测试的事情进行单元测试,那将很有用在重要的情况下手动处理。

如果不清楚我所说的一致性是什么意思,对于hashCodeequals,我指的是以下内容:

If two objects are equal according to the equals(Object) method, then calling the hashCode method on each of the two objects must produce the same integer result.

对于equalscompareTo,我指的是以下内容:

The natural ordering for a class C is said to be consistent with equals if and only if e1.compareTo(e2) == 0 has the same boolean value as e1.equals(e2) for every e1 and e2 of class C.

【问题讨论】:

标签: java unit-testing equals hashcode compareto


【解决方案1】:

Guava's 测试有一个名为EqualsTester 的实用程序,我们将其用作单元测试的日常部分来测试equalshashCode。它的用途看起来像

new EqualsTester()
  .addEqualityGroup("hello", "h" + "ello")
  .addEqualityGroup("world", "wor" + "ld")
  .addEqualityGroup(2, 1 + 1)
  .testEquals();

它测试同一组中的所有值是否相等并且具有相同的哈希码,不同的组相等,并且各种其他不变量都被满足。你可以自己使用它,或者只是借用它的想法。

如果可以在不生成或明确指定测试值的情况下进行测试,我会感到非常惊讶,因为这似乎非常很可能等同于停机问题。

【讨论】:

    【解决方案2】:

    我写了一些实用方法来帮助单元测试 hashCode 和 equals 方法:

    http://softsmithy.sourceforge.net/devlib/docs/api/org/softsmithy/devlib/junit/Tests.html

    该库是开源的,可以从这里下载: http://sourceforge.net/projects/softsmithy/files/softsmithy-devlib/v0.1/

    或使用 Maven:

        <dependency>
            <groupId>org.softsmithy.devlib</groupId>
            <artifactId>devlib-core</artifactId>
            <version>0.1</version>
            <scope>test</scope>
        </dependency>
    

    【讨论】:

      【解决方案3】:

      有一个非常酷的工具,叫做 Korat,它可以进行详尽的搜索来检查 Java 类在小情况下的正确性。它实际上查看执行的代码,以便构建程序可以实际区分的给定大小的所有不同测试用例。我不知道它在大型案例中有多有用,但是对于许多程序来说,它可以用来自动检查这样的案例是否正常工作。

      希望这会有所帮助!

      【讨论】:

      【解决方案4】:

      我最近使用 meanbean (http://meanbean.sourceforge.net/) 来自动测试一个类的 equals() 和 hashCode() 合约(加上 setter/getter 对)。

      “平均豆:

      1. 测试JavaBean/POJO 的getter 和setter 方法对功能是否正确。 2. 验证一个类的equals和hashCode方法分别符合Equals Contract和HashCode Contract。 3. 验证对象相等性中的属性重要性。”

      我还有很多关于meanbean 的问题:它是否验证equals() 和hashCode() 的一致性。另外,我还没有努力打败它。我相信它不支持 compareTo()。而且我还没有尝试过替代品。对他人的经验感兴趣。

      【讨论】:

        【解决方案5】:

        如果您使用的是 JUnit,则扩展包具有 EqualsHashCodeTestCase,它针对 Java 规范中概述的所有内容(自反、传递、对称等)对 equals 和 hashCode 进行了全面测试。您所要做的就是为父类提供一个相等和不相等的对象用于检查。

        由于 CompareTo 方法是 Comparable 接口的一部分,它实际上被拆分为另一个测试用例 - ComparabilityTestCase。这需要三个对象 - 较小值、相等值和较大值之一。覆盖这些,父类将处理其余部分。

        【讨论】:

        • 这看起来很有希望。当我开始调查他们时,如果他们做我认为他们做的事情,那么你很可能会得到我的绿色复选标记。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-11-19
        • 2012-02-01
        • 1970-01-01
        • 2014-08-12
        • 2010-09-29
        • 1970-01-01
        相关资源
        最近更新 更多