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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4449728/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-14 17:41:12  来源:igfitidea点击:

How can I do unit test for hashCode()?

javaunit-testingjunithashcode

提问by Tomasz Gutkowski

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

如何在单元测试中测试hashCode() 函数?

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

采纳答案by duffymo

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.

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

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

当我检查对 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());
}

回答by Bozho

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)

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

回答by Peter Lawrey

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.

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

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

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

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

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

回答by Danubian Sailor

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.

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

回答by DerMike

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()类似return 1;.

回答by Devesh Chanchlani

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.

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