如何在unit testing中测试hashCode()函数?
public int hashCode(){
int result = 17 + hashDouble(re);
result = 31 * result + hashDouble(im);
return result;
}
答案 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));
}