用Java维护对象方法契约的自动单元测试?

Jul*_*lie 10 java testing junit unit-testing

在开发Java应用程序时,我经常重写Object方法(通常是equals和hashCode).我想通过某种方式系统地检查我是否遵守每个类的Object方法的合同.例如,我希望测试断言对于相等的对象,哈希码也是相等的.我正在使用JUnit测试框架,所以我最好想要一些JUnit解决方案,我可以自动生成这些测试,或者一些测试用例可以以某种方式访问​​我的所有类并确保合同得到维护.

我正在使用JDK6和JUnit 4.4.

Von*_*onC 1

只是对这个问题的一些初步想法(这可以解释为什么整整一个小时后仍然没有答案!?;)

在实施问题的解决方案时似乎有两个部分:

1/检索我自己的每个课程。很简单,你给出一个 jar 名称,Junit 测试初始化​​方法将:

  • 检查该 jar 是否在 JUnit 执行类路径中
  • 读取并加载其中的每个类
  • 仅记住那些已声明和重新定义的 equals() 和 hash() (通过反射)

2/测试每个对象
...其中存在一个问题:您必须实例化这些对象,即创建两个实例,并将它们用于 equals() 测试。

这意味着如果你的构造函数接受参数,你必须考虑,

  • 对于基本类型参​​数(int、boolean、float...)或 String,限制值的每个组合(对于 String,"xxx"、""、null;对于 int、0、-x、+x、-Integer .MIN、+Integer.MAX、...等等)
  • 对于非原始类型,构建一个要传递给要测试的对象的构造函数的实例(这意味着您必须递归地考虑该参数的构造函数参数:是否是原始类型)

最后,并非为这些构造函数自动创建的每个参数都以功能方式有意义,这意味着其中一些值将无法构建实例,因为必须检测到 Assert: 。

然而这似乎是可能的(如果你愿意,你可以将其设为代码挑战),但我想让其他 StackOverflow 读者首先对这个问题做出回应,因为他们可能会看到一个比我简单得多的解决方案。


为了避免组合问题并保持测试相关测试值接近实际代码本身,我建议定义专用注释,并用 String 表示构造函数的有效值。它将位于您的对象之一的 equals() 重写方法的正上方。

然后将读取这些注释值,并将组合从这些注释值创建的实例以测试 equals()。这将使组合的数量足够少

侧节点:通用 JUnit 测试用例当然会检查,对于每个要测试的 equals() ,是否存在:

  • 如上所述的一些注释(除非只有默认构造函数可用)
  • 相应的 hash() 方法也被重写(如果没有,如果会抛出断言异常并在该类上失败)