我应该单元测试hashCode/equals/toString吗?

Ger*_*cke 14 java unit-testing qa code-coverage

编写Java类时,使用IDE生成方法并不罕见

  • toString()
  • equals()
  • hashCode()

但是一旦使用IDE生成它们,它们就会成为代码库的一部分(在SCM中),因此所有质量测量方法都适用.

特别是equals和hashcode方法包含许多条件.如果我不编写单元测试,代码覆盖率(line-,condition-,mutation-)的得分相当低,特别是如果被测试的类不那么大.

一些覆盖工具支持过滤(即cobertura),其他(即jacoco)则不支持.但覆盖工具只露出一个症状 - 未经测试的代码 - 因此我不是在问,是否要抑制/忽略症状,而是如何处理根本原因.

问题是:我应该为这些方法编写单元测试吗?

  • 如果是的话,有什么理由这样做?什么是明智的做法?
  • 如果不是,为什么不呢?

我不是要求一般生成的类,比如JAXB pojos,WS-Clients等,它们可以很容易地自动生成并从覆盖率分析中排除.

Rol*_*and 12

如果你生成这些方法,你可能也应该为它生成测试;-)

手动测试这些方法可能很麻烦,但根据您希望通过测试确保的方法,测试这些方法也许值得.反问题:你会测试日志声明吗?

这实际上取决于你想要完成的事情.有些人会说:不要,别人可能会说:做.

考虑不测试此类方法的一些原因:

  • 代码生成并可能包含许多字段.测试它可能导致许多各种组合,这些组合只是编写/维护很麻烦,也许发电机已经测试好了吗?;-)
  • 你没有通过实施测试获得任何价值.您的toString()只会被日志或调试器使用,所以您甚至不关心.
  • 你相信,生成的代码是安全的足够hashcodeequals

测试此类方法的原因:

  • 确保结果符合预期
  • 您希望确保如果重新生成这些方法,它不会破坏以前的方法实现用法
  • toString()除了记录之外你还使用你的方法,不希望某些东西出现在那里.正如Hulk所说,你可能还想确保某些东西甚至不会出现在日志中.

但这些都是相当弥补的.在最后的项目中,我没有测试toString(),equals或者hashCode很少,因为它没有被认为是必要的,每个人都同意.

这可能归结为:您希望代码的安全性如何以及对您(或您的企业或客户;-)的价值有多大)


Kar*_*nek 8

IDE生成的hashCode/equals的问题是它可能与对象本身不同步(例如,当您添加新字段时).因此,我建议为hashCode和equals创建测试.

手动编写这些当然是次优的.您可以使用EqualsVerifier项目等自动化工具将这些工具作为单行程序.

toString是一个不同的野兽,因为它没有定义任何合同.如果你只是为了获得更好的调试体验而使用toString,我就不会测试它,只是将其从覆盖率计算中删除.