Интеграционное тестирование в Spring: TestContext Framework, конфигурация TestExecutionListener

Spring предоставляет следующие реализации TestExecutionListener, которые регистрируются по умолчанию, в следующем порядке:

  • ServletTestExecutionListener: настраивает Servlet API моки для WebApplicationContext.
  • DirtiesContextBeforeModesTestExecutionListener: обрабатывает аннотацию @DirtiesContext для режимов "до" (“before”).
  • DependencyInjectionTestExecutionListener: обеспечивает внедрение зависимостей для тестового экземпляра.
  • DirtiesContextTestExecutionListener: обрабатывает аннотацию @DirtiesContext для режимов "после" (“after”).
  • TransactionalTestExecutionListener: обеспечивает выполнение транзакционного теста с семантикой отката по умолчанию.
  • SqlScriptsTestExecutionListener: запускает сценарии SQL, настроенные с помощью аннотации @Sql.
  • EventPublishingTestExecutionListener: публикует события выполнения теста в ApplicationContext теста.

Регистрация реализаций TestExecutionListener

Вы можете зарегистрировать реализации TestExecutionListener для тестового класса и его подклассов с помощью аннотации @TestExecutionListeners.

Автоматическое обнаружение реализаций TestExecutionListener по умолчанию

Регистрация реализаций TestExecutionListener с помощью @TestExecutionListeners подходит для настраиваемых прослушивателей, которые используются в ограниченных сценариях тестирования. Однако это может стать громоздким, если настраиваемый прослушиватель необходимо использовать во всем наборе тестов. Эта проблема решается путем поддержки автоматического обнаружения реализаций TestExecutionListener по умолчанию с помощью механизма SpringFactoriesLoader.

В частности, модуль spring-test объявляет все основные реализации TestExecutionListener по умолчанию под ключом org.springframework.test.context.TestExecutionListener в своем файле свойств META-INF/spring.factories. Сторонние фреймворки и разработчики могут внести свои собственные реализации TestExecutionListener в список слушателей по умолчанию таким же образом через свой собственный файл свойств META-INF/spring.factories.

Упорядочивание реализаций TestExecutionListener

Когда инфраструктура TestContext обнаруживает реализации TestExecutionListener по умолчанию с помощью вышеупомянутого механизма SpringFactoriesLoader, созданные экземпляры слушателей сортируются с помощью Spring AnnotationAwareOrderComparator, который учитывает интерфейс Spring Ordered и аннотацию @Order для упорядочивания. AbstractTestExecutionListener и все реализации TestExecutionListener по умолчанию, предоставляемые Spring, реализуют интерфейс Ordered с соответствующими значениями. Поэтому сторонние фреймворки и разработчики должны убедиться, что их реализации TestExecutionListener по умолчанию зарегистрированы в правильном порядке, реализовав Ordered или объявив @Order.

Слияние реализаций TestExecutionListener

Если пользовательский TestExecutionListener зарегистрирован через @TestExecutionListeners, прослушиватели по умолчанию не регистрируются. В большинстве распространенных сценариев тестирования это фактически заставляет разработчика вручную объявлять все прослушиватели по умолчанию в дополнение к любым настраиваемым прослушивателям. Следующий листинг демонстрирует этот стиль конфигурации:

@ContextConfiguration
@TestExecutionListeners({
    MyCustomTestExecutionListener.class,
    ServletTestExecutionListener.class,
    DirtiesContextBeforeModesTestExecutionListener.class,
    DependencyInjectionTestExecutionListener.class,
    DirtiesContextTestExecutionListener.class,
    TransactionalTestExecutionListener.class,
    SqlScriptsTestExecutionListener.class
})
class MyTest {
    // тело класса...
}

Проблема с этим подходом заключается в том, что он требует, чтобы разработчик точно знал, какие слушатели зарегистрированы по умолчанию. Более того, набор прослушивателей по умолчанию может меняться от релиза к релизу - например, SqlScriptsTestExecutionListener был представлен в Spring Framework 4.1, а DirtiesContextBeforeModesTestExecutionListener был представлен в Spring Framework 4.2. Кроме того, сторонние фреймворки, такие как Spring Boot и Spring Security, регистрируют свои собственные реализации TestExecutionListener по умолчанию с помощью вышеупомянутого механизма автоматического обнаружения.

Чтобы не знать и повторно объявлять всех слушателей по умолчанию, вы можете установить для атрибута mergeMode @TestExecutionListeners значение MergeMode.MERGE_WITH_DEFAULTS. MERGE_WITH_DEFAULTS указывает, что локально объявленные прослушиватели должны быть объединены со слушателями по умолчанию. Алгоритм слияния обеспечивает удаление дубликатов из списка и сортировку результирующего набора объединенных слушателей в соответствии с семантикой AnnotationAwareOrderComparator. Если слушатель реализует Ordered или аннотирован с помощью @Order, он может повлиять на позицию, в которой он объединяется, со значениями по умолчанию. В противном случае локально объявленные прослушиватели добавляются к списку прослушивателей по умолчанию при объединении.

Например, если класс MyCustomTestExecutionListener в предыдущем примере настраивает значение своего порядка (например, 500) так, чтобы оно было меньше порядка ServletTestExecutionListener (который оказывается 1000), MyCustomTestExecutionListener может быть автоматически объединен со списком значений по умолчанию. перед ServletTestExecutionListener, а предыдущий пример можно заменить следующим:

@ContextConfiguration
@TestExecutionListeners(
    listeners = MyCustomTestExecutionListener.class,
    mergeMode = MERGE_WITH_DEFAULTS
)
class MyTest {
    // тело класса...
}


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


Комментарии

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

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

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

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