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 實作

如果您擴充以 @TestExecutionListeners 註解的類別,且您需要切換為使用預設的 Listener 集合,您可以使用以下項目註解您的類別。

  • Java

  • Kotlin

// Switch to default listeners
@TestExecutionListeners(
	listeners = {},
	inheritListeners = false,
	mergeMode = MERGE_WITH_DEFAULTS)
class MyTest extends BaseTest {
	// class body...
}
// Switch to default listeners
@TestExecutionListeners(
	listeners = [],
	inheritListeners = false,
	mergeMode = MERGE_WITH_DEFAULTS)
class MyTest : BaseTest {
	// class body...
}

自動探索預設 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,您可以將 @TestExecutionListenersmergeMode 屬性設定為 MergeMode.MERGE_WITH_DEFAULTSMERGE_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...
}