【发布时间】:2010-12-15 12:12:03
【问题描述】:
如何测试unit testing 中的hashCode() 函数?
public int hashCode(){
int result = 17 + hashDouble(re);
result = 31 * result + hashDouble(im);
return result;
}
【问题讨论】:
标签: java unit-testing junit hashcode
如何测试unit testing 中的hashCode() 函数?
public int hashCode(){
int result = 17 + hashDouble(re);
result = 31 * result + hashDouble(im);
return result;
}
【问题讨论】:
标签: java unit-testing junit hashcode
每当我重写 equals 和 hash 代码时,我都会按照 Joshua Bloch 在“Effective Java”第 3 章中的建议编写单元测试。我确保 equals 和 hash 代码是自反的、对称的和传递的。我还确保“不等于”适用于所有数据成员。
当我检查对 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());
}
【讨论】:
当您编写一般的数学函数(如哈希码)时,您会在测试中测试一些示例,直到您确信该函数按预期工作。有多少示例取决于您的功能。
对于哈希码函数,我认为您至少要测试两个被认为相等的不同对象具有相同的哈希码。喜欢
assertNotSame(obj1, obj2); // don't cheat
assertEquals(obj1.hashcode(), obj2.hashcode());
您还应该测试两个不同的值是否具有不同的哈希码,以避免像return 1; 那样实现hashcode()。
【讨论】:
hashCode 被覆盖,以使具有相同字段的实例与 HashSet/HashMap 等相同。 所以 Junit 测试应该断言两个具有相同值的不同实例返回相同的 hashCode。
【讨论】:
创建许多(数百万个)可复制的随机对象,并将所有 hashCodes 添加到一个 Set 中,并检查您得到的几乎和许多 unqiue 值作为生成 id 的数量。为了使它们可随机复制,请使用固定的随机种子。
另外检查您是否可以将这些项目添加到 HashSet 并再次找到它们。 (使用具有相同值的不同对象)
确保您的 equals() 与您的 hashCode() 行为相匹配。我还会检查您的字段是否都是最终字段。
【讨论】:
我认为没有必要对哈希码方法进行单元测试。特别是如果它是由您的 IDE 或 HashCodeBuilder (apache commons) 生成的
【讨论】:
除了@duffymo 测试哈希码是自反的、对称的和传递的,另一种测试方法是通过“映射”,这是哈希码真正派上用场的地方。
@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));
}
【讨论】: