简体   繁体   English

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

[英]How can I do unit test for hashCode()?

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

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. 每当我重写equals和hash代码时,我都会按照Joshua Bloch在“Effective Java”第3章中的建议编写单元测试。我确保equals和hash代码是自反的,对称的和传递的。 I also make sure that "not equals" works properly for all the data members. 我还确保“not equals”适用于所有数据成员。

When I check the call to equals, I also make sure that the hashCode behaves as it should. 当我检查对equals的调用时,我也确保hashCode的行为应该如此。 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; 此外,您应该测试两个不同的值具有不同的哈希码,以避免实现hashcode()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. 创建许多(数百万)可再现的随机对象,并将所有hashCodes添加到Set中,并检查您获得几乎和许多unqiue值作为生成ID的数量。 To make them reproduceable random use a fixed random seed. 为了使它们可再现,随机使用固定的随机种子。

Additionally check you can add these Items to a HashSet and find them again. 另外,检查是否可以将这些项添加到HashSet并再次找到它们。 (Using a differnt object with the same values) (使用具有相同值的不同对象)

Make sure your equals() matches your hashCode() behaviour. 确保你的equals()与你的hashCode()行为相匹配。 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) 特别是如果它是由IDE或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. 除了@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));
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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