自动检查equals、hashCode和compareTo的一致性的技术是什么?

20

我很清楚合同需要确保hashCodeequals一致,equalscompareTo也一致。然而,在实践中,这经常被违反。是否有任何工具、技术或库可以自动测试这种一致性?

不幸的是,我怀疑答案是否定的,但能够有一个单元测试来检测这种事情并利用库调用或框架将会很有用,而不需要为每个重要的情况手动编写自定义测试。

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

如果两个对象根据equals(Object)方法是相等的,则在这两个对象上调用hashCode方法必须产生相同的整数结果。

对于equalscompareTo,我参考了以下内容:

如果对于类C,当且仅当e1.compareTo(e2) == 0与e1.equals(e2)具有相同的布尔值时,类C的自然排序被认为是与equals一致的。


1
只需将一些对象放入HashMapTreeMap中,然后看看能否取回它们;-) - user207421
参见:https://dev59.com/12gv5IYBdhLWcg3wY_42 - Ralph
5个回答

12

Guava 的测试工具中有一个叫做 EqualsTester 的实用程序,我们在单元测试的日常工作中使用它来测试equalshashCode。 它的使用方式如下:

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

这个测试确保同一组中的所有值都相等并具有相同的哈希码,不同组之间不相等,并且满足各种其他不变性。你可以使用它自己,或者借鉴它的思想。

如果在生成或明确指定测试值的情况下进行测试似乎很可能等价于停机问题,那么我会非常惊讶。


5
如果您正在使用JUnit,扩展包中有EqualsHashCodeTestCase,它完全测试了Java规范中概述的所有内容的equals和hashCode(自反,传递,对称等)。您只需要提供一个相等和一个不相等的对象供父类用于检查即可。
由于CompareTo方法是Comparable接口的一部分,它实际上被拆分成另一个测试用例 - ComparabilityTestCase。这需要三个对象 - 一个较小的值、一个相等的值和一个较大的值。覆盖这些并且父类会处理其余的内容。

这看起来很有前途。当我开始调查它们时,如果它们确实做我认为它们会做的事情,那么你很可能会从我这里获得绿色勾号。 - Michael McGowan

1

1

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

希望这可以帮到你!


你喜欢一篇关于Korrat的论文。Korrat主页是:http://korat.sourceforge.net/。 - Ralph

1

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

“Mean Bean:

1. 测试JavaBean / POJO的getter和setter方法对是否正确运行。
2. 验证类的equals和hashCode方法是否符合Equals Contract和HashCode Contract。
3. 在对象相等性中验证属性显着性。”

我仍然有很多关于meanbean的问题:它是否验证equals()和hashCode()的一致性。此外,我没有刻意想要打败它。我相信它不支持compareTo()。我也没尝试其他替代品。有兴趣了解其他人的经验。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接