When developing Java applications, I often override Object methods (usually equals and hashCode). I would like some way to systematically check that I'm adhering to the contract for Object methods for every one of my classes. For example, I want tests that assert that for equal objects, the hash code is also equal. I'm using the JUnit test framework, so preferably I'd like some JUnit solution where I can automatically generate these tests, or some test case that can somehow visit all of my classes and make sure that the contract is upheld.
I'm using JDK6 and JUnit 4.4.
public static void checkObjectIdentity(Object a1, Object a2, Object b1) { assertEquals(a1, a2); assertEquals(a2, a1); assertNotSame(a1, a2); assertEquals(a1.hashCode(), a2.hashCode()); assertFalse(a1.equals(b1)); assertFalse(a2.equals(b1)); assertFalse(b1.equals(a1)); assertFalse(b1.equals(a2)); }
Usage:
checkObjectIdentity(new Integer(3), new Integer(3), new Integer(4));
Can't think of anything better. Add new calls to checkObjectIdentity when you find a bug.
Just a some initial thoughts on that question (which may explain why there are still no answer after a full hour!? ;)
There seems to be two parts when it comes to implement a solution to the question:
1/ retrieve every classes of my own. Easy, you give a jar name, the Junit test initialization method would:
2/ test every objects
... and therein lies the catch: you have to instantiate those objects, that is create two instances, and use them for equals() tests.
That means if your constructors are taken arguments, you have to consider,
Finally, not every parameters automatically created for those constructor would make sense in a functional way, meaning some of those values will fail to build the instance because of an Assert: that must be detected.
Yet it seems to be possible (you can make it a code-challenge if you want), but I want first let other StackOverflow readers respond to this issue, as they may see a far simpler solution that I am.
To avoid combinations problem and to keep test relevant testing values close to the actual code itself, I would recommend the definition of an dedicated annotation, with a String representing valid values for constructors. There would be located right above the equals() overridden method of one of your object.
Those annotation values would then be read, and the instances created from those would be combined for testing equals(). That would keep the number of combinations down enough
Side-node: a generic JUnit test case would of course check that, for each equals() to tests, there is:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With