Ответ 1
Простой: перед каждым тестом начинайте новую транзакцию и после теста откатывайте ее. Это даст вам ту же базу данных, что и раньше.
Убедитесь, что тесты не создают новых транзакций; вместо этого повторно используйте существующий.
Я хочу очистить базу данных после каждого тестового примера без отката транзакции. Я пробовал DBUnit DatabaseOperation.DELETE_ALL, но он не работает, если удаление нарушает ограничение внешнего ключа. Я знаю, что я могу отключить проверки внешнего ключа, но это также отключит проверки тестов (которые я хочу предотвратить).
Я использую JUnit 4, JPA 2.0 (Eclipselink) и базу данных Derby в памяти. Любые идеи?
Спасибо, Тео
Простой: перед каждым тестом начинайте новую транзакцию и после теста откатывайте ее. Это даст вам ту же базу данных, что и раньше.
Убедитесь, что тесты не создают новых транзакций; вместо этого повторно используйте существующий.
Самый простой способ сделать это - это, вероятно, использовать метод nativeQuery jpa.
@After
public void cleanup() {
EntityManager em = entityManagerFactory.createEntityManager();
em.getTransaction().begin();
em.createNativeQuery("truncate table person").executeUpdate();
em.createNativeQuery("truncate table preferences").executeUpdate();
em.getTransaction().commit();
}
Да, тест в транзакции сделает вашу жизнь намного проще, но если транзакция - это ваша вещь, тогда вам нужно реализовать компенсирующие транзакции во время очистки (в @After
). Это кажется трудоемким, и если возможно, вы можете получить набор вспомогательных методов (в тестах), которые компенсируют (очищают) данные, накопленные в течение @Before
, и тесты (используя JPA или прямой JDBC - что имеет смысл).
Например, если вы используете JPA и вызываете методы создания для сущностей во время тестов, вы можете использовать (используя AOP, если вы представляете себе или просто вспомогательные методы тестирования, подобные нам), образец для всех тестов:
@After
Я немного смущен, поскольку DBUnit будет повторно инициализировать базу данных до известного состояния перед каждым тестом.
Они также рекомендуют как наилучшую практику не очищать или иным образом изменять данные после теста.
Итак, если это очистка, вы должны подготовить db для следующего теста, я бы не стал беспокоиться.
Моя настройка очень похожа: это Derby (встроенный) + OpenJPA 1.2.2 + DBUnit. Вот как я обрабатываю интеграционные тесты для моей текущей задачи: в каждом методе @Before
я запускаю 3 скрипта:
Моя база данных имеет только 12 таблиц, а набор тестовых данных не очень большой, либо — около 50 записей. Каждый script занимает около 500 мс для запуска, и я поддерживаю их вручную, когда таблицы добавляются или изменяются.
Этот подход, вероятно, не рекомендуется для тестирования больших баз данных, и, возможно, его нельзя даже считать хорошей практикой для малых; однако у него есть одно важное преимущество перед откатом транзакции в методе @After
: вы можете фактически обнаружить, что происходит при совершении (например, сохраняющиеся отдельные объекты или исключения оптимистичного блокирования).