开发者

How can I do unit test for hashCode()?

开发者 https://www.devze.com 2023-01-30 22:18 出处:网络
How can I test the hashCode() function in unit testing? public int hashCode(){ int result = 17 + hashDouble(re);

How can I test the hashCode() function in unit testing?

public int hashCode(){
    int result = 17 + hashDouble(re);
    res开发者_如何转开发ult = 31 * result + hashDouble(im);
    return result;
}


Whenever I override equals and hash code, I write unit tests that follow Joshua Bloch's recommendations in "Effective Java" Chapter 3. I make sure that equals and hash code are reflexive, symmetric, and transitive. I also make sure that "not equals" works properly for all the data members.

When I check the call to equals, I also make sure that the hashCode behaves as it should. Like this:

@Test
public void testEquals_Symmetric() {
    Person x = new Person("Foo Bar");  // equals and hashCode check name field value
    Person y = new Person("Foo Bar");
    Assert.assertTrue(x.equals(y) && y.equals(x));
    Assert.assertTrue(x.hashCode() == y.hashCode());
}


When you write a mathematical function in general (like hash code) you test some examples in your tests until you are convinced that the function works as expected. How many examples that are depends on your function.

For a hash code function I'd think you test at least that two distinct objects, that are considered equal have the same hash code. Like

assertNotSame(obj1, obj2); // don't cheat
assertEquals(obj1.hashcode(), obj2.hashcode());

Further you should test that two different values have different hash codes to avoid implementing hashcode() like return 1;.


hashCode is overrided so as to make instances with same fields identical for HashSet/HashMap etc. So Junit test should assert that two different instances with same values return identical hashCode.


Create many (millions of) reproduceably random objects and add all the hashCodes to a Set and check you get almost and many unqiue values as the number of generate ids. To make them reproduceable random use a fixed random seed.

Additionally check you can add these Items to a HashSet and find them again. (Using a differnt object with the same values)

Make sure your equals() matches your hashCode() behaviour. I would also check that your fields are all final.


I don't think there's a need to unit-test a hashcode method. Especially if it is generated by either your IDE or a HashCodeBuilder (apache commons)


Apart from @duffymo test for hashcode being reflexive, symmetric, and transitive, another way of testing would be via "Map" which is where hashcodes actually come handy.

 @Test
public void testHashcode() {
    Person p1 = new Person("Foo Bar"); 
    Person p2 = new Person("Foo Bar");
    Map<Person, String> map = new HashMap<>();
    map.put(p1, "dummy");
    Assert.assertEquals("dummy", map.get(p2));
}
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号