web-dev-qa-db-ja.com

hashCode()の単体テストを行うにはどうすればよいですか?

単体テスト でhashCode()関数をテストするにはどうすればよいですか?

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

等値とハッシュコードをオーバーライドするときはいつでも、「Effective Java」の第3章にあるJoshua Blochの推奨に従うユニットテストを記述します。等値とハッシュコードが再帰的、対称的、推移的であることを確認します。 「等しくない」がすべてのデータメンバーに対して適切に機能することも確認します。

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

一般的な数学関数(ハッシュコードなど)を作成するときは、関数が期待どおりに機能することが確認できるまで、テストでいくつかの例をテストします。関数に依存する例の数。

ハッシュコード関数の場合、少なくとも、等しいと見なされる2つの異なるオブジェクトが同じハッシュコードを持っていることをテストすると思います。お気に入り

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

さらに、_return 1;_のようにhashcode()を実装しないように、2つの異なる値が異なるハッシュコードを持っていることをテストする必要があります。

5
DerMike

多くの(何百万もの)再現可能なランダムオブジェクトを作成し、すべてのハッシュコードをセットに追加し、生成IDの数としてほとんどすべてのunqiue値を取得することを確認します。それらをランダムに再現可能にするには、固定ランダムシードを使用します。

さらに、これらの項目をHashSetに追加して、再び見つけることができることを確認してください。 (同じ値を持つ別のオブジェクトを使用)

Equals()がhashCode()の動作と一致することを確認してください。また、フィールドがすべて最終であることも確認します。

4
Peter Lawrey

hashSet/HashMapなどの同じフィールドを持つインスタンスを同一にするために、hashCodeがオーバーライドされます。したがって、Junitテストは、同じ値を持つ2つの異なるインスタンスが同じhashCodeを返すことを表明する必要があります。

3
Danubian Sailor

ハッシュコードメソッドを単体テストする必要はないと思います。特に、IDEまたは HashCodeBuilder (Apache commons)のいずれかによって生成された場合

1
Bozho

ハッシュコードが再帰的、対称的、推移的であることを@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));
}
0