Подтвердить что ты не робот

Как я могу сделать unit test для hashCode()?

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

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

Ответ 1

Всякий раз, когда я переопределяю equals и хэш-код, я пишу модульные тесты, которые следуют рекомендациям Джошуа Блоха в "Эффективной Java". Глава 3. Я убеждаюсь, что 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());
}

Ответ 2

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

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

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

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

Ответ 3

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

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

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

Ответ 4

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

Ответ 5

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

Ответ 6

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