Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Should I unit test hashCode/equals/toString?

Tags:

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.

like image 430
Gerald Mücke Avatar asked Mar 21 '17 13:03

Gerald Mücke


People also ask

Is it necessary to override hashCode and equals method?

You must override hashCode() in every class that overrides equals(). Failure to do so will result in a violation of the general contract for Object. hashCode(), which will prevent your class from functioning properly in conjunction with all hash-based collections, including HashMap, HashSet, and Hashtable.

Why we check hashCode () equality before equals () method?

If an object's hashcode is not the same as another object's hashcode, there is no reason to execute the equals() method: you just know the two objects are not the same. On the other hand, if the hashcode is the same, then you must execute the equals() method to determine whether the values and fields are the same.

Why should we override hashCode and equals method in Java?

Overriding only equals() method without overriding hashCode() causes the two equal instances to have unequal hash codes, which violates the hashCode contract (mentioned in Javadoc) that clearly says, if two objects are equal according to the equals(Object) method, then calling the hashCode method on each of the two ...

What is the importance of hashCode () and equals () methods?

The equals() and hashcode() are the two important methods provided by the Object class for comparing objects. Since the Object class is the parent class for all Java objects, hence all objects inherit the default implementation of these two methods.


2 Answers

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 ;-))

like image 175
Roland Avatar answered Oct 25 '22 12:10

Roland


The problem with IDE generated hashCode/equals is that it can get out of sync with the object itself (for example when you add new fields). I would therefore advise to create tests for hashCode and equals.

It would be of course sub-optimal to write these by hand. You can use automated tools such as the EqualsVerifier project to make these a one-liner.

toString is a different beast as it doesn't have any contract defined. If you use toString just to get a nicer debugging experience, I wouldn't test it and would just remove it from coverage calculations.

like image 25
Karel Petranek Avatar answered Oct 25 '22 13:10

Karel Petranek