Интеграционное тестирование в Spring: TestContext Framework, аннотации транзакций
В следующем примере на основе JUnit Jupiter показан вымышленный сценарий тестирования интеграции, в котором выделены все аннотации, связанные с транзакциями. Этот пример не предназначен для демонстрации передового опыта, а скорее для демонстрации того, как можно использовать эти аннотации.
@SpringJUnitConfig
@Transactional(transactionManager = "txMgr")
@Commit
class FictitiousTransactionalTest {
@BeforeTransaction
void verifyInitialDatabaseState() {
// логика для проверки
// начального состояния перед запуском транзакции
}
@BeforeEach
void setUpTestDataWithinTransaction() {
// настраиваем тестовые данные внутри транзакции
}
@Test
// переопределяет аннотацию @Commit уровня класса
@Rollback
void modifyDatabaseWithinTransaction() {
// логика, которая использует
// тестовые данные и изменяет состояние базы данных
}
@AfterEach
void tearDownWithinTransaction() {
// запускаем логику "разрыва" внутри транзакции
}
@AfterTransaction
void verifyFinalDatabaseState() {
// логика для проверки
// конечного состояния после отката транзакции
}
}
Избегайте ложных срабатываний при тестировании кода ORM
Когда вы тестируете код приложения, который манипулирует состоянием сеанса Hibernate или контекстом сохранения JPA, не забудьте очистить базовую единицу работы в тестовых методах, которые запускают этот код. Неспособность очистить базовую единицу работы может привести к ложным срабатываниям: ваш тест проходит успешно, но тот же код вызывает исключение в действующей производственной среде. Обратите внимание, что это применимо к любому ORM фреймворку, который поддерживает единицу работы в памяти. В следующем примере тестового случая на основе Hibernate один метод демонстрирует ложное срабатывание, а другой метод правильно отображает результаты сброса сеанса:
@Autowired
SessionFactory sessionFactory;
@Transactional
@Test // исключение не ожидается!
public void falsePositive() {
updateEntityInHibernateSession();
// Ложное срабатывание: исключение будет
// сгенерировано после перехода в спящий режим.
// Сессия окончательно очищена
// (т.е. в производственном коде)
}
@Transactional
@Test(expected = ...)
public void updateWithSessionFlush() {
updateEntityInHibernateSession();
// Ручной flush необходим,
// чтобы избежать ложного срабатывания теста
sessionFactory.getCurrentSession().flush();
}
// ...
В следующем примере показаны методы сопоставления для JPA:
// ...
@PersistenceContext
EntityManager entityManager;
@Transactional
@Test // исключение не ожидается!
public void falsePositive() {
updateEntityInJpaPersistenceContext();
// Ложное срабатывание: будет сгенерировано исключение,
// когда JPA EntityManager окончательно очищен
// (т.е. в производственном коде)
}
@Transactional
@Test(expected = ...)
public void updateWithEntityManagerFlush() {
updateEntityInJpaPersistenceContext();
// Ручной flush необходим,
// чтобы избежать ложного срабатывания теста
entityManager.flush();
}
// ...
Читайте также:
- Интеграционное тестирование в Spring: TestContext Framework, включение и отключение транзакций
- Интеграционное тестирование в Spring: TestContext Framework, программное управление транзакциями
- Интеграционное тестирование в Spring: TestContext Framework, управление транзакциями
Комментарии
Отправить комментарий