Java – Should I unit test hashCode/equals/toString


When writing Java classes, it's not uncommon to generate methods using your IDE such as

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

But once you've generated them using the IDE, they become part of your codebase (in SCM) and therefore all quality measuring means apply.

Especially the equals and hashcode methods contain lots of conditions. If I don't write unit tests, the score on code coverage (line-, condition-, mutation-) is pretty low, especially if the class under test is not that large.

Some coverage tools support filtering (i.e. cobertura), others (i.e. jacoco) don't. But the coverage tools reveal just a symptom – untested code – and therefore I'm not asking, whether to suppress/ignore the symptom, but how to deal with the root cause.

Question is: should I write unit tests for these methods?

  • If yes, what are good reasons to do so? And what is a sensible approach?
  • If no, why not?

I'm not asking for generated classes in general, like JAXB pojos, WS-Clients etc, which can be easily generated automatically and excluded from coverage analysis.

Best Solution

If you generate those methods, you should probably also generate the tests for it ;-)

It may be cumbersome to test those methods by hand but depending on what you want to ensure with your tests, it might be worth to test those methods as well. Counter-question: would you test log-statements?

It really depends on what you are trying to accomplish. Some will say: don't, others may say: do.

Thinking about some reasons to not test such methods:

  • code is generated and may contain lots of fields. testing it may lead to lots of various combinations which would just be cumbersome to write/maintain and maybe the generator was already tested good enough? ;-)
  • you do not gain any value by implementing tests for it. Your toString() will only be used by logs or by the debugger, so you don't even care.
  • you trust that the generated code is safe enough for hashcode and equals

Reasons to test such methods:

  • to ensure that the outcome is as expected
  • you want to ensure that if you regenerate those methods, it doesn't break previous method implementation usages
  • you use your toString()-method besides logging and don't want certain things to show up there. As Hulk stated, you may also want to ensure that certain things don't even show up in logs.

But these were rather made up. In the last projects I did not test toString() and equals or hashCode only seldomly as it wasn't considered necessary and everyone agreed.

It may all come down to: how safe you want your code to be and how much worth is it to you (or your business or your customer ;-))