简体   繁体   中英

How can I do unit test for hashCode()?

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

public int hashCode(){
    int result = 17 + hashDouble(re);
    result = 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; .

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.

hashCode被覆盖,以便使具有相同字段的实例与HashSet / HashMap等相同。因此,Junit测试应断言具有相同值的两个不同实例返回相同的hashCode。

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM