測試執行事件

EventPublishingTestExecutionListener 提供了一種實現自定義 TestExecutionListener 的替代方法。測試的 ApplicationContext 中的元件可以監聽由 EventPublishingTestExecutionListener 釋出的以下事件,每個事件都對應於 TestExecutionListener API 中的一個方法。

  • BeforeTestClassEvent

  • PrepareTestInstanceEvent

  • BeforeTestMethodEvent

  • BeforeTestExecutionEvent

  • AfterTestExecutionEvent

  • AfterTestMethodEvent

  • AfterTestClassEvent

這些事件可以出於各種原因被消費,例如重置 mock bean 或跟蹤測試執行。消費測試執行事件而不是實現自定義 TestExecutionListener 的一個優點是,測試執行事件可以由註冊在測試 ApplicationContext 中的任何 Spring bean 消費,並且這些 bean 可以直接受益於依賴注入和 ApplicationContext 的其他特性。相比之下,TestExecutionListener 不是 ApplicationContext 中的 bean。

EventPublishingTestExecutionListener 預設是註冊的;但是,它只在 ApplicationContext *已經被載入*後才釋出事件。這可以防止 ApplicationContext 被不必要地或過早地載入。

因此,BeforeTestClassEvent 不會發布,直到 ApplicationContext 被另一個 TestExecutionListener 載入後才會釋出。例如,對於預設註冊的 TestExecutionListener 實現集合,使用特定測試 ApplicationContext 的第一個測試類不會發布 BeforeTestClassEvent,但對於使用相同測試 ApplicationContext 的同一測試套件中的任何後續測試類,*將*釋出 BeforeTestClassEvent,因為在後續測試類執行時,上下文已經載入(前提是上下文沒有透過 @DirtiesContext 或最大大小逐出策略從 ContextCache 中移除)。

如果你希望確保 BeforeTestClassEvent 總是為每個測試類釋出,你需要註冊一個在 beforeTestClass 回撥中載入 ApplicationContextTestExecutionListener,並且該 TestExecutionListener 必須註冊在 EventPublishingTestExecutionListener *之前*。

類似地,如果在給定測試類的最後一個測試方法之後使用 @DirtiesContext 從上下文快取中移除 ApplicationContext,則不會為該測試類釋出 AfterTestClassEvent

為了監聽測試執行事件,Spring bean 可以選擇實現 org.springframework.context.ApplicationListener 介面。或者,可以使用 @EventListener 註解標記監聽器方法,並配置為監聽上述特定事件型別之一(參見 基於註解的事件監聽器)。由於這種方法的流行,Spring 提供了以下專用的 @EventListener 註解來簡化測試執行事件監聽器的註冊。這些註解位於 org.springframework.test.context.event.annotation 包中。

  • @BeforeTestClass

  • @PrepareTestInstance

  • @BeforeTestMethod

  • @BeforeTestExecution

  • @AfterTestExecution

  • @AfterTestMethod

  • @AfterTestClass

異常處理

預設情況下,如果測試執行事件監聽器在消費事件時丟擲異常,該異常將傳播到底層使用的測試框架(例如 JUnit 或 TestNG)。例如,如果消費 BeforeTestMethodEvent 導致異常,則相應的測試方法將因此失敗。相比之下,如果非同步測試執行事件監聽器丟擲異常,該異常不會傳播到底層測試框架。有關非同步異常處理的更多詳細資訊,請查閱 @EventListener 的類級別 javadoc。

非同步監聽器

如果你希望某個特定的測試執行事件監聽器非同步處理事件,你可以使用 Spring 的常規 @Async 支援。有關更多詳細資訊,請查閱 @EventListener 的類級別 javadoc。