Spring надає наступні реалізації TestExecutionListener
, які реєструються за
замовчуванням, точно так:
-
ServletTestExecutionListener
: Конфігурує об'єкти-імітації API-інтерфейсу сервлетів дляWebApplicationContext
. -
DirtiesContextBeforeModesTestExecutionListener
: Обробляє анотацію @DirtiesContext для режимів "перед". -
ApplicationEventsTestExecutionListener
: Забезпечує підтримкуApplicationEvents
. -
DependencyInjectionTestExecutionListener
: Забезпечує впровадження залежностей для тестового екземпляра. -
DirtiesContextTestExecutionListener
: Обробляє анотацію @DirtiesContext для режимів "після". -
TransactionalTestExecutionListener
: Забезпечує транзакційне виконання тестів із семантикою відкату за замовчуванням. -
SqlScriptsTestExecutionListener
: Виконує SQL-скрипти, налаштовані за допомогою анотації @Sql. -
EventPublishingTestExecutionListener
: Публікує події виконання тесту
вApplicationContext
.
Реєстрація реалізацій TestExecutionListener
Можна зареєструвати реалізацію TestExecutionListener
для тестового класу та його підкласів за допомогою
анотації @TestExecutionListeners
. Подробиці та приклади дивися у підрозділі, присвяченому підтримці
анотацій, та javadoc про анотацію @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
, створені екземпляри слухачів сортуються за допомогою AnnotationAwareOrderComparator
Ordered
зі Spring та анотації @Order
для впорядкування. AbstractTestExecutionListener
та всі реалізації TestExecutionListener
за замовчуванням, що надаються Spring, реалізують
Ordered
з відповідними значеннями. Тому стороннім фреймворкам та розробникам слід переконатися, що їх
реалізації TestExecutionListener
за замовчуванням реєструються в правильному порядку, реалізуючи Ordered
або оголошуючи анотацію @Order
. Дивися javadoc за методами getOrder()
основних реалізацій
TestExecutionListener
за замовчуванням для отримання більш детальної інформації про те, які значення
надаються кожному основному слухачеві.
Об'єднання реалізацій TestExecutionListener
Якщо спеціальний слухач TestExecutionListener
зареєстрований через анотацію @TestExecutionListeners
,
слухачі за замовчуванням не реєструються. У найпоширеніших сценаріях тестування це фактично змушує розробника вручну
оголошувати всі слухачі за замовчуванням на додаток до будь-яких спеціальних слухачів. Наступний лістинг демонструє
цей стиль конфігурації:
@ContextConfiguration
@TestExecutionListeners({
MyCustomTestExecutionListener.class,
ServletTestExecutionListener.class,
DirtiesContextBeforeModesTestExecutionListener.class,
DependencyInjectionTestExecutionListener.class,
DirtiesContextTestExecutionListener.class,
TransactionalTestExecutionListener.class,
SqlScriptsTestExecutionListener.class
})
class MyTest {
// Тіло класу...
}
@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. До того ж, сторонні фреймворки, такі як Spring Boot і Spring Security, реєструють власні
реалізації TestExecutionListener
за замовчуванням, використовуючи згаданий вище механізм автоматичного
виявлення.
Щоб уникнути необхідності знати та повторно оголошувати всіх слухачів за замовчуванням, можна встановити атрибут
mergeMode
анотації @TestExecutionListeners
у MergeMode.MERGE_WITH_DEFAULTS
.
MERGE_WITH_DEFAULTS
вказує, що локально оголошені слухачі мають бути об'єднані зі слухачами за
замовчуванням. Алгоритм об'єднання забезпечує видалення дублікатів зі списку та сортування отриманого набору
об'єднаних слухачів відповідно до семантики AnnotationAwareOrderComparator
, як описано в розділі
"Упорядкування реалізацій TestExecutionListener"
. Якщо слухач реалізує Ordered
або
позначений анотацією @Order
, він може впливати на позицію, в якій він об'єднується зі слухачами за
замовчуванням. Інакше локально оголошені слухачі додаються до списку слухачів за замовчуванням під час об'єднання.
Наприклад, якщо клас MyCustomTestExecutionListener
у попередньому прикладі конфігурує своє значення
order
(наприклад, 500
) таким чином, що воно буде менше значення черговості ServletTestExecutionListener
(який дорівнює 1000
), то MyCustomTestExecutionListener
може бути автоматично об'єднаний зі
списком значень за замовчуванням перед ServletTestExecutionListener
, а попередній приклад можна буде
замінити наступним:
@ContextConfiguration
@TestExecutionListeners(
listeners = MyCustomTestExecutionListener.class,
mergeMode = MERGE_WITH_DEFAULTS
)
class MyTest {
// Тіло класу...
}
@ContextConfiguration
@TestExecutionListeners(
listeners = [MyCustomTestExecutionListener::class],
mergeMode = MERGE_WITH_DEFAULTS
)
class MyTest {
// Тіло класу...
}
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ