Интеграционное тестирование - Hibernate & DbUnit - PullRequest
4 голосов
/ 03 мая 2010

Я пишу несколько интеграционных тестов в JUnit.Здесь происходит то, что, когда я запускаю все тесты вместе в строке (а не отдельно), данные, сохраненные в базе данных, всегда изменяются, и тесты находят неожиданные данные (вставленные предыдущим тестом) во время их выполнения.1002 * Я думал об использовании DbUnit, но мне интересно, сбрасывает ли он индекс автоинкремента между каждым выполнением или нет (потому что тесты также проверяют идентификаторы сохраняемых объектов).1006 * M.

Ответы [ 4 ]

9 голосов
/ 03 мая 2010

Рекомендуется переводить базу данных в известное состояние до выполнения теста, а DBUnit предоставляет все необходимое для этого. Но не полагайтесь на автоматически увеличенные столбцы, поместите их также в свой набор данных DBUnit. Плюсы: вы можете вручную проверить состояние базы данных после выполнения теста, который не проходит. Минусы: вам нужно настроить и поддерживать наборы данных.

Другой подход заключается в запуске каждого метода тестирования внутри транзакции (и откат транзакции в конце выполнения). Плюсы: данные проще в настройке и обслуживании (в базе данных). Минусы: исправление неудачного теста менее удобно.

3 голосов
/ 03 мая 2010

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

Кроме того, ваша тестовая база данных может быть создана с помощью сценариев. Здесь может помочь DbUnit, как и другие генераторы баз данных, такие как LiquiBase , dbmaintain , dbmigrate Затем вы можете удалить всю базу данных и создать заново для каждого теста или теста группа. Полезность этого подхода уменьшается по мере того, как набор тестовых данных становится большим и увеличивается объем служебных данных.

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

РЕДАКТИРОВАТЬ: ОП спросил об использовании спящего режима для воссоздания схемы. Это можно сделать, создав новую SessionFactory для каждого теста и установив "hibernate.hbm2ddl.auto" в "true" при сборке SessionFactory. Я упоминаю о снижающейся эффективности drop-create - она ​​применима и к этому случаю.

2 голосов
/ 03 мая 2010

Плохо полагаться на значения идентификатора в тесте, потому что автоинкремент зависит только от базы данных. Поэтому я бы никогда не проверял идентификаторы, потому что если вы это сделаете, ваш тест зависит от того, что сущности заполнены определенными значениями идентификаторов, что не является реальным примером из жизни. Тест должен быть независимым от идентификаторов автоинкремента.

1 голос
/ 03 мая 2010

По сути, эту проблему можно решить двумя способами.

  1. Оберните связанные с БД тесты в транзакции. Перед началом теста начните транзакцию. После завершения тестового прогона транзакция всегда отменяется. Таким образом, изменения, внесенные в тест, не будут сохранены.

  2. Используйте что-то вроде DBUnit и т. Д. Для макета классов, связанных с операциями БД, чтобы данные никогда не поступали в БД, а ваши классы возвращают результаты, как будто операция БД была выполнена.

Если вы получаете доступ к БД при выполнении ваших тестов, я предпочитаю подход 1.

...