Интеграционное тестирование в Spring: TestContext Framework, управление транзакциями

В TestContext framework транзакциями управляет TransactionalTestExecutionListener, который настроен по умолчанию, даже если вы явно не объявляете @TestExecutionListeners в своем тестовом классе. Однако, чтобы включить поддержку транзакций, вы должны сконфигурировать bean-компонент PlatformTransactionManager в ApplicationContext, который загружается с семантикой @ContextConfiguration. Кроме того, вы должны объявить аннотацию Spring @Transactional либо на уровне класса, либо на уровне метода для ваших тестов.

Тестовые транзакции

Транзакции, управляемые тестом, - это транзакции, которые управляются декларативно с помощью TransactionalTestExecutionListener или программно с помощью TestTransaction. Вы не должны путать такие транзакции с транзакциями, управляемыми Spring (те, которые управляются непосредственно Spring в ApplicationContext, загруженном для тестов) или транзакциями, управляемыми приложением (те, которые управляются программно в коде приложения, который вызывается тестами). Транзакции, управляемые Spring и приложениями, обычно участвуют в транзакциях, управляемых тестами. Однако следует проявлять осторожность, если транзакции, управляемые Spring или приложениями, настроены с любым типом распространения, кроме REQUIRED или SUPPORTS.

Превентивные таймауты и транзакции, управляемые тестами

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

В частности, поддержка тестирования Spring связывает состояние транзакции с текущим потоком (через переменную java.lang.ThreadLocal) до вызова текущего метода тестирования. Если фреймворк тестирования вызывает текущий метод тестирования в новом потоке для поддержки упреждающего таймаута, любые действия, выполняемые в текущем методе тестирования, не будут вызываться в транзакции, управляемой тестом. Следовательно, результат любых таких действий не будет отменен с помощью транзакции, управляемой тестом. Напротив, такие действия будут зафиксированы в постоянном хранилище - например, в реляционной базе данных - даже если Spring правильно откатывает транзакцию, управляемую тестом.

Ситуации, в которых это может произойти, включают, помимо прочего, следующие.

  • Поддержка @Test(timeout = …) в JUnit 4 и правило TimeOut
  • Методы assertTimeoutPreemptively(…) JUnit Jupiter в классе org.junit.jupiter.api.Assertions
  • Поддержка @Test(timeOut = …) TestNG

Читайте также:


Комментарии

Популярные сообщения из этого блога

Методы класса Object в Java

Как получить текущий timestamp в Java

Основные опции JVM для повышения производительности и отладки