Como posso fazer teste de unidade para hashCode ()?

Como posso testar a function hashCode () no teste de unidade ?

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

Sempre que eu substituo equals e hash code, eu escrevo testes unitários que seguem as recomendações de Joshua Bloch em “Effective Java”, capítulo 3. Eu me certifico de que equals e hash code sejam reflexivos, simétricos e transitivos. Eu também me certifico de que “não é igual” funciona corretamente para todos os membros de dados.

Quando eu verifico a chamada para iguais, também me certifico de que o hashCode se comporta como deveria. Como isso:

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

Quando você escreve uma function matemática em geral (como código hash), você testa alguns exemplos em seus testes até estar convencido de que a function funciona conforme o esperado. Quantos exemplos são dependentes da sua function.

Para uma function de código hash, acho que você testa pelo menos que dois objects distintos, que são considerados iguais, têm o mesmo código hash. Gostar

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

Além disso, você deve testar se dois valores diferentes têm códigos hash diferentes para evitar a implementação de hashcode() como return 1; .

Crie muitos (milhões de) objects aleatoriamente reproduzíveis e adicione todos os hashCodes a um Conjunto e verifique se você obtém quase e muitos valores unquadrados como o número de ids de geração. Para torná-los randoms reprodutíveis, use uma semente aleatória fixa.

Além disso, verifique se você pode adicionar esses itens a um HashSet e localizá-los novamente. (Usando um object diferente com os mesmos valores)

Certifique-se de que seu equals () corresponda ao seu comportamento hashCode (). Eu também verifico se seus campos são todos finais.

O hashCode é substituído para tornar as instâncias com os mesmos campos idênticas para HashSet / HashMap, etc. Portanto, o teste do Junit deve afirmar que duas instâncias diferentes com os mesmos valores retornam o hashCode idêntico.

Eu não acho que há uma necessidade de testar um método hashcode. Especialmente se for gerado pelo seu IDE ou por um HashCodeBuilder (apache commons)

Além do teste @duffymo para o hashcode ser reflexivo, simétrico e transitivo, outra maneira de testar seria via “Map”, que é onde os hashcodes realmente são úteis.

  @Test public void testHashcode() { Person p1 = new Person("Foo Bar"); Person p2 = new Person("Foo Bar"); Map map = new HashMap<>(); map.put(p1, "dummy"); Assert.assertEquals("dummy", map.get(p2)); }