測試中的 Bean 覆蓋

測試中的 Bean 覆蓋指的是透過在測試類上或測試類中的一個或多個非靜態欄位上添加註解,來覆蓋測試類的 ApplicationContext 中特定 bean 的能力。

此功能旨在作為一種風險較低的替代方案,以取代透過 @Bean 並將 DefaultListableBeanFactorysetAllowBeanDefinitionOverriding 標誌設定為 true 來註冊 bean 的做法。

Spring TestContext 框架提供了兩組用於 bean 覆蓋的註解。

前者純粹依賴 Spring,而後者依賴於 Mockito 第三方庫。

自定義 Bean 覆蓋支援

上述三個註解都基於 @BeanOverride 元註解及相關基礎設施,允許定義自定義 bean 覆蓋變體。

要實現自定義 bean 覆蓋支援,需要以下內容:

  • 一個帶有 @BeanOverride 元註解的註解,用於定義要使用的 BeanOverrideProcessor

  • 一個自定義的 BeanOverrideProcessor 實現

  • 一個或多個由處理器建立的具體 BeanOverrideHandler 實現

Spring TestContext 框架包含了以下 API 的實現,這些 API 支援 bean 覆蓋並負責設定其餘基礎設施。

  • 一個 BeanFactoryPostProcessor

  • 一個 ContextCustomizerFactory

  • 一個 TestExecutionListener

spring-test 模組在其 META-INF/spring.factories 屬性檔案中註冊了後兩者的實現(BeanOverrideContextCustomizerFactoryBeanOverrideTestExecutionListener)。

bean 覆蓋基礎設施會搜尋測試類上的註解以及測試類中帶有 @BeanOverride 元註解的非靜態欄位上的註解,並例項化相應的 BeanOverrideProcessor,該處理器負責建立適當的 BeanOverrideHandler

內部的 BeanOverrideBeanFactoryPostProcessor 隨後使用 bean 覆蓋處理器,透過建立、替換或包裝 bean(如相應 BeanOverrideStrategy 定義)來修改測試的 ApplicationContext

REPLACE

替換 bean。如果相應的 bean 不存在,則丟擲異常。

REPLACE_OR_CREATE

如果 bean 存在,則替換它。如果相應的 bean 不存在,則建立一個新 bean。

WRAP

檢索原始 bean 並將其包裝。

當替換一個非單例 bean 時,該非單例 bean 將被替換為與適用 BeanOverrideHandler 建立的 bean 覆蓋例項相對應的單例 bean,並且相應的 bean 定義將被轉換為 singleton。因此,如果處理器覆蓋了一個 prototype 或作用域 bean,則被覆蓋的 bean 將被視為一個 singleton

當替換由 FactoryBean 建立的 bean 時,FactoryBean 本身將被替換為與適用 BeanOverrideHandler 建立的 bean 覆蓋例項相對應的單例 bean。

當包裝由 FactoryBean 建立的 bean 時,被包裝的是由 FactoryBean 建立的物件,而不是 FactoryBean 本身。

與 Spring 的自動裝配機制(例如,@Autowired 欄位的解析)相反,TestContext 框架中的 bean 覆蓋基礎設施在定位 bean 時所能執行的啟發式搜尋是有限的。BeanOverrideProcessor 可以計算要覆蓋的 bean 的名稱,或者在給定帶註解欄位的型別及其限定註解的情況下,可以明確選擇該 bean。

通常,BeanOverrideFactoryPostProcessor 會“按型別”選擇 bean。或者,使用者可以直接在自定義註解中提供 bean 名稱。

BeanOverrideProcessor 實現也可以根據約定或其他方法在內部計算 bean 名稱。

© . This site is unofficial and not affiliated with VMware.