We’ve been creating several Java Beans that have an imperative need to have both equals and hashCode working correctly. To do this, we started off writing a series of test cases which made sure that for every field we exposed that the objects were / were not equal based on if the field was set, and that the field was taken into account as part of the hashCode calculation. After doing two of these, I figured there had to be a better way, and after some research, ended up writing a BeanTestCase class which exposes an assertMeetsEqualsContract method and an assertMeetsHashCodeContract method. Note that while there are projects out there (like Assertion Extensions for JUnit) that have assertions for equals and hashCode, they don’t actually walk the fields of the objects and test the various scenarios of changing each field.
After I had written this, I applied it to classes we already had unit tests for around equals and hashCode – and immediately found a bug in one of the classes where we missed a field. That paid for itself right away. ;)
Being that I’m just getting back into the Java world, if there are better ways, please let me know!
- Download BeanTestCase.java
Looks great, I’m gonna give it a try!
Awesome senor. You may have saved me like 3 hours of work. I will be sure to credit you in the source.
You made amistake when you set o2 with double value in assertMeetsEqualsContract. There have to be 0 ;) (or something else than 1 ). But afterall it’s great job ;).
This is really helpful, thanks. Supplements well with one of my last articles, how to effectivly implement equals(), hashCode(), compareTo() and toString():
http://bwinterberg.blogspot.com/2009/08/building-equals-hashcode-compareto-and.html
привет лунатикам!
The code won’t work if the class is having reference types :(
Hi,
I had to add the following lines:
if (Modifier.isFinal(field.getModifiers() ))
{
continue;
}
In order to let it work with final fields. The lines were added before the field.getType() sequences of if(s)