TestExecutionListener
組態
Spring 提供以下 TestExecutionListener
實作,預設會依下列順序註冊
-
ServletTestExecutionListener
:為WebApplicationContext
組態 Servlet API Mock。 -
DirtiesContextBeforeModesTestExecutionListener
:處理「之前」模式的@DirtiesContext
註解。 -
ApplicationEventsTestExecutionListener
:提供ApplicationEvents
的支援。 -
BeanOverrideTestExecutionListener
:提供 測試中的 Bean 覆寫 的支援。 -
DependencyInjectionTestExecutionListener
:為測試實例提供依賴注入。 -
MicrometerObservationRegistryTestExecutionListener
:提供 Micrometer 的ObservationRegistry
支援。 -
DirtiesContextTestExecutionListener
:處理「之後」模式的@DirtiesContext
註解。 -
CommonCachesTestExecutionListener
:在必要時清除測試ApplicationContext
中的資源快取。 -
TransactionalTestExecutionListener
:提供具有預設回滾語意的交易測試執行。 -
SqlScriptsTestExecutionListener
:執行使用@Sql
註解組態的 SQL 腳本。 -
EventPublishingTestExecutionListener
:將測試執行事件發佈到測試的ApplicationContext
(請參閱 測試執行事件)。 -
MockitoResetTestExecutionListener
:重設由@MockitoBean
或@MockitoSpyBean
組態的 Mock。
註冊 TestExecutionListener
實作
您可以使用 @TestExecutionListeners
註解,為測試類別、其子類別及其巢狀類別明確註冊 TestExecutionListener
實作。請參閱 註解支援 和 @TestExecutionListeners
的 javadoc 以取得詳細資訊和範例。
切換為預設
TestExecutionListener 實作如果您擴充以
|
自動探索預設 TestExecutionListener
實作
使用 @TestExecutionListeners
註冊 TestExecutionListener
實作適用於在有限的測試案例中使用的自訂 Listener。但是,如果自訂 Listener 需要在整個測試套件中使用,則可能會變得繁瑣。此問題透過支援透過 SpringFactoriesLoader
機制自動探索預設 TestExecutionListener
實作來解決。
例如,spring-test
模組在其 META-INF/spring.factories
屬性檔案中,在 org.springframework.test.context.TestExecutionListener
金鑰下宣告所有核心預設 TestExecutionListener
實作。第三方框架和開發人員可以透過自己的 spring.factories
檔案,以相同的方式將自己的 TestExecutionListener
實作貢獻到預設 Listener 列表中。
排序 TestExecutionListener
實作
當 TestContext 框架透過 前述 SpringFactoriesLoader
機制探索預設 TestExecutionListener
實作時,實例化的 Listener 會使用 Spring 的 AnnotationAwareOrderComparator
排序,這會遵循 Spring 的 Ordered
介面和 @Order
註解進行排序。Spring 提供的 AbstractTestExecutionListener
和所有預設 TestExecutionListener
實作都使用適當的值實作 Ordered
。因此,第三方框架和開發人員應確保透過實作 Ordered
或宣告 @Order
,將其預設 TestExecutionListener
實作以正確的順序註冊。請參閱核心預設 TestExecutionListener
實作的 getOrder()
方法的 javadoc,以取得指派給每個核心 Listener 的值的詳細資訊。
合併 TestExecutionListener
實作
如果透過 @TestExecutionListeners
註冊自訂 TestExecutionListener
,則不會註冊預設 Listener。在大多數常見的測試案例中,這實際上會強制開發人員手動宣告所有預設 Listener 以及任何自訂 Listener。以下清單示範了此組態樣式
-
Java
-
Kotlin
@ContextConfiguration
@TestExecutionListeners({
MyCustomTestExecutionListener.class,
ServletTestExecutionListener.class,
DirtiesContextBeforeModesTestExecutionListener.class,
DependencyInjectionTestExecutionListener.class,
DirtiesContextTestExecutionListener.class,
TransactionalTestExecutionListener.class,
SqlScriptsTestExecutionListener.class
})
class MyTest {
// class body...
}
@ContextConfiguration
@TestExecutionListeners(
MyCustomTestExecutionListener::class,
ServletTestExecutionListener::class,
DirtiesContextBeforeModesTestExecutionListener::class,
DependencyInjectionTestExecutionListener::class,
DirtiesContextTestExecutionListener::class,
TransactionalTestExecutionListener::class,
SqlScriptsTestExecutionListener::class
)
class MyTest {
// class body...
}
此方法的挑戰在於它需要開發人員確切知道預設註冊了哪些 Listener。此外,預設 Listener 的集合可能會因版本而異 — 例如,SqlScriptsTestExecutionListener
是在 Spring Framework 4.1 中引入的,而 DirtiesContextBeforeModesTestExecutionListener
是在 Spring Framework 4.2 中引入的。此外,Spring Boot 和 Spring Security 等第三方框架會使用前述 自動探索機制 註冊自己的預設 TestExecutionListener
實作。
為了避免必須知道和重新宣告所有預設 Listener,您可以將 @TestExecutionListeners
的 mergeMode
屬性設定為 MergeMode.MERGE_WITH_DEFAULTS
。MERGE_WITH_DEFAULTS
表示應將本機宣告的 Listener 與預設 Listener 合併。合併演算法可確保從列表中移除重複項目,並根據 排序 TestExecutionListener
實作 中描述的 AnnotationAwareOrderComparator
的語意對產生的合併 Listener 集合進行排序。如果 Listener 實作 Ordered
或以 @Order
註解,則它可以影響其與預設值合併的位置。否則,本機宣告的 Listener 在合併時會附加到預設 Listener 列表。
例如,如果上一個範例中的 MyCustomTestExecutionListener
類別將其 order
值 (例如 500
) 組態為小於 ServletTestExecutionListener
的順序 (恰好為 1000
),則 MyCustomTestExecutionListener
可以自動與 ServletTestExecutionListener
前面的預設值列表合併,而上一個範例可以替換為以下項目
-
Java
-
Kotlin
@ContextConfiguration
@TestExecutionListeners(
listeners = MyCustomTestExecutionListener.class,
mergeMode = MERGE_WITH_DEFAULTS
)
class MyTest {
// class body...
}
@ContextConfiguration
@TestExecutionListeners(
listeners = [MyCustomTestExecutionListener::class],
mergeMode = MERGE_WITH_DEFAULTS
)
class MyTest {
// class body...
}