如何为hashCode()进行单元测试?

时间:2010-12-15 12:12:03

标签: java unit-testing junit hashcode

如何在unit testing中测试hashCode()函数?

public int hashCode(){
    int result = 17 + hashDouble(re);
    result = 31 * result + hashDouble(im);
    return result;
}

6 个答案:

答案 0 :(得分:73)

每当我覆盖equals和hash代码时,我都会按照Joshua Bloch在“Effective Java”第3章中的建议编写单元测试。我确保equals和hash代码是自反的,对称的和可传递的。我还确保“not equals”适用于所有数据成员。

当我检查对equals的调用时,我也确保hashCode的行为应该如此。像这样:

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

答案 1 :(得分:5)

当您编写一般数学函数(如哈希代码)时,您会在测试中测试一些示例,直到您确信该函数按预期工作。有多少例子取决于你的功能。

对于哈希码函数,我认为你至少测试了两个被认为相等的不同对象具有相同的哈希码。像

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

此外,您应该测试两个不同的值具有不同的哈希码,以避免实现hashcode()之类的return 1;

答案 2 :(得分:4)

创建许多(数百万个)可重现的随机对象,并将所有hashCodes添加到Set中,并检查您获得几乎和许多unqiue值作为生成ID的数量。为了使它们可以重现随机使用固定的随机种子。

另外,检查是否可以将这些项添加到HashSet并再次找到它们。 (使用具有相同值的不同对象)

确保你的equals()与你的hashCode()行为相匹配。我还会检查你的领域是否都是最终的。

答案 3 :(得分:3)

重写hashCode,以便为HashSet / HashMap等创建具有相同字段的实例。 所以Junit测试应断言具有相同值的两个不同实例返回相同的hashCode。

答案 4 :(得分:1)

我认为不需要对哈希码方法进行单元测试。特别是如果它是由IDE或HashCodeBuilder(apache commons)生成的

答案 5 :(得分:0)

除了@duffymo测试哈希码是自反,对称和传递之外,另一种测试方式是通过“Map”,这是哈希码实际上派上用场的地方。

 @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));
}
相关问题