Как я могу сделать модульный тест для hashCode ()? - PullRequest
35 голосов
/ 15 декабря 2010

Как проверить функцию hashCode () в модульном тестировании ?

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

Ответы [ 6 ]

73 голосов
/ 15 декабря 2010

Всякий раз, когда я переопределяю равенства и хэш-код, я пишу модульные тесты, которые следуют рекомендациям Джошуа Блоха в главе «Эффективная Java». Я проверяю, что равные и хэш-код являются рефлексивными, симметричными и транзитивными.Я также проверяю, что «не равно» работает правильно для всех членов данных.

Когда я проверяю вызов на 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());
}
5 голосов
/ 15 декабря 2010

Когда вы пишете математическую функцию в целом (например, хэш-код), вы тестируете несколько примеров в своих тестах, пока не убедитесь, что функция работает должным образом. Сколько примеров зависит от вашей функции.

Для функции хеш-кода я думаю, что вы тестируете, по крайней мере, два разных объекта, которые считаются равными, имеют одинаковый хеш-код. Как

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

Далее вы должны проверить, что два разных значения имеют разные хеш-коды, чтобы избежать реализации hashcode(), как return 1;.

4 голосов
/ 15 декабря 2010

Создайте много (миллионы) воспроизводимых случайных объектов и добавьте все хэш-коды в набор и убедитесь, что вы получаете почти и много уникальных значений в качестве числа генерируемых идентификаторов.Чтобы сделать их воспроизводимыми случайным образом, используйте фиксированное случайное начальное число.

Дополнительно проверьте, что вы можете добавить эти элементы в HashSet и найти их снова.(Использование другого объекта с одинаковыми значениями)

Убедитесь, что ваш метод equals () соответствует вашему поведению hashCode ().Я также проверил бы, что все ваши поля являются окончательными.

3 голосов
/ 15 декабря 2010

hashCode переопределяется, чтобы сделать экземпляры с одинаковыми полями идентичными для HashSet / HashMap и т. Д. Поэтому тест Junit должен утверждать, что два разных экземпляра с одинаковыми значениями возвращают идентичный hashCode.

1 голос
/ 15 декабря 2010

Я не думаю, что есть необходимость в модульном тестировании метода хэш-кода.Особенно если он генерируется вашей IDE или HashCodeBuilder (apache commons)

0 голосов
/ 17 апреля 2017

Помимо теста @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));
}
...