Сравнение сущностей во время модульного тестирования с Hibernate - PullRequest
1 голос
/ 03 июня 2009

Я запускаю тесты JUnit, используя в памяти HSQLDB. Допустим, у меня есть метод, который вставляет некоторые значения в БД, и я проверяю, правильно ли метод вставил значения. Обратите внимание, что порядок вставки не важен.

@Test
public void should_insert_correctly() {
    MyEntity[] expectedEntities = new MyEntity[2];
    // init expected entities

    Inserter out = new Inserter(session); // out: object under test
    out.insert();

    List list = session.createCriteria(MyEntity.class).list();

    assertTrue(list.contains(expectedEntities[0]));
    assertTrue(list.contains(expectedEntities[1]));
}

Проблема в том, что я не могу сравнить ожидаемые объекты с фактическими, потому что ожидаемый идентификатор и фактический идентификатор разные. Поскольку setId () MyEntity является приватным (чтобы не задавать идентификатор явно), я не могу установить для всех идентификаторов сущностей значение 0 и сравнить их так.

Как я могу сравнить два набора результатов независимо от их идентификаторов?

Ответы [ 3 ]

2 голосов
/ 04 июня 2009

Я нашел это более практичным. Вместо того, чтобы получать все результаты сразу, я выбираю результаты в соответствии с критериями и утверждаю, что они не равны нулю.

public void should_insert_correctly() {
    Inserter out = new Inserter(session); // out: object under test
    out.insert();

    Criteria criteria;

    criteria = getCriteria(session, 0);
    assertNotNull(criteria.uniqueResult());

    criteria = getCriteria(session, 1);
    assertNotNull(criteria.uniqueResult());
}

private Criteria getCriteria(Session session, int i) {
    Criteria criteria = session.createCriteria(MyEntity.class);
    criteria.add(Restrictions.eq("x", expectedX[i]));
    criteria.add(Restrictions.eq("y", expectedY[i]));
    return criteria;
}
0 голосов
/ 03 июня 2009

Я бы попытался реализовать метод Object.equals(Object) в вашем MyEntity классе.

List.contains(Object) использует Object.equals(Object) (Источник: Java 6 API ), чтобы определить, находится ли Объект в этом списке.

Метод session.createCriteria(MyEntity.class).list(); возвращает список новых экземпляров со значениями, которые вы вставили (надеюсь).
Так что вам нужно сравнить значения. Это легко сделать с помощью реализации Object.equals(Object).

Редактирование разъяснений:
Вы можете игнорировать идентификаторы в вашем методе equals, чтобы сравнение касалось только «реальных значений».

YAE (еще одно редактирование):
Я рекомендую прочитать эту статью о методе equals(): Анжелика Лангер: Секреты равных . Очень хорошо объясняет всю справочную информацию.

0 голосов
/ 03 июня 2009

Сущность с состоянием не должна переопределять equals, то есть сущности должны сравниваться на равенство по ссылочной идентичности, поэтому List.contains не будет работать так, как вы хотите.

Я использую отражение, чтобы сравнить поля исходных и перезагруженных объектов. Функция, которая проходит по полям объектов, игнорирует переходные поля и поля, помеченные как @ Transient.

Мне не нужно игнорировать идентификатор. Когда объект впервые сбрасывается в базу данных, Hibernate назначает ему идентификатор. Когда он будет перезагружен, объект будет иметь тот же идентификатор.

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

...