搶先一步
VMware 提供培訓和認證,以加速您的進展。
了解更多Spring Framework 6.2.0-M1
已發佈,其中包含解決超過一百個問題的變更。其中包含 Spring 測試支援中的一系列新功能。
在這篇文章中,我想帶您了解其中一個新的測試功能:Bean 覆寫支援。
使用 Spring TestContext Framework,您可以透過註解驅動模型,輕鬆驗證 Spring 應用程式在整合測試中的正確配置。
在單元測試中,依賴注入和 Spring 設計原則使您的程式碼更少依賴容器,並更容易手動 Stub 或 Mock 元件的依賴項,以便隔離測試它。在整合測試中,這不太相關,因為測試旨在涵蓋元件的正確配置。儘管您可能會發現需要替換整合測試中 Bean 的情況。
Spring Framework 團隊通常不建議重新定義 Bean。雖然目前在 BeanDefinitionRegistry
的預設實作中可以透過標誌來實現,但我們計劃棄用它,而 Spring Boot 已經預設關閉 Bean 覆寫來選擇退出。
然而,這在生產程式碼中更令人擔憂,我們認識到在測試中覆寫 Bean 是有用且合理的。因此,我們的目標是在該領域為常見的覆寫情境提供一流的安排。
在 Spring Framework 6.2.0-M1
中,我們引入了一個可擴展的 Bean 覆寫功能,它將允許您精確且明確地替換整合測試中的一個或多個 Bean 定義,同時防止在生產程式碼或測試的其他部分中發生此類意外變更。
@TestBean
的簡單方法基礎覆寫Spring TestContext Framework 現在提供了一個簡單的 Bean 覆寫支援實作:@TestBean
註解。
覆寫名為 example
的 Bean 分為三個步驟:新增一個以 Bean 名稱命名的欄位,使用 @TestBean
註解標註它,並新增一個名為 exampleTestOverride
的 0 參數 static
工廠方法。在該工廠方法中,例如,如果 Bean 類型是介面,您可以傳回簡化的實作,如下列範例所示
@Configuration
class ProdConfiguration {
@Bean
MyService customService() {
return new ProdServiceImpl();
}
}
@SpringJUnitConfig
class MyServiceIntegrationTests {
@TestBean
MyService customService;
static MyService customServiceTestOverride() {
return new SimplifiedServiceImpl();
}
@Test
void test(ApplicationContext context) {
assertThat(context.getBean("customService")
.isSameAs(this.customService)
.isInstanceOf(SimplifiedServiceImpl.class);
//...
}
}
除非為 @TestBean
註解提供 beanName
屬性,否則註解欄位的名稱會被解釋為目標 Bean 的名稱。
methodName
參數也可以用於指向不遵循 {beanName}TestOverride
預設命名慣例的工廠方法。
Bean 覆寫機制負責解析此註解,並負責替換登錄檔中現有的 Bean 定義。測試類別中的 customService
欄位也會注入由 customServiceTestOverride
工廠方法產生的覆寫實例。
@MockitoBean
和 @MockitoSpyBean
第二個 Bean 覆寫實作基於 Mockito 函式庫。它帶有兩個註解:@MockitoBean
用於自動將目標單例 Bean 替換為 Mock 物件,而 @MockitoSpyBean
用於將 Bean 包裝在 Spy 物件中。
每個註解都有特定於 Mockito 的屬性,以便進一步配置應如何 Mock 目標 Bean。這包括支援指定如何在測試之間重設 Mock 物件,如下列範例所示
@Configuration
class ProdConfiguration {
@Bean
MyService customService() {
return new ProdService();
}
}
@SpringJUnitConfig
class MyServiceIntegrationTests {
@MockitoSpyBean(reset = MockReset.NONE)
MyService customService;
@Test
void test() {
//...
}
}
在上面的範例中,Spy 物件在測試之間不會被重設。預設情況下,Mock 物件和 Spy 物件在測試方法執行後重設。
請注意,為了 Spy 一個 Bean,首先必須存在 Spy 類別的實際實例。除了更常見的替換 Bean 定義的情況之外,Bean 覆寫功能還支援這種特殊情況,並允許在 Bean 實例化後從中繼資料建立覆寫。
測試支援中的新 Bean 覆寫以註解基礎模型的形式出現,適用於您測試類別中的欄位。它是可擴展和可自訂的,上面介紹的 3 個註解只是我們開箱即用提供的預設實作。
實作您自己的 Bean 覆寫風格與實作以下內容一樣簡單
@BeanOverride
Meta-Annotation 註解的註解,它定義要使用的 BeanOverrideProcessor
。BeanOverrideProcessor
實作本身。OverrideMetadata
實作。Spring TestContext Framework 解析測試類別,尋找任何使用 @BeanOverride
Meta-Annotation 註解的欄位,並實例化相關的 BeanOverrideProcessor
,以便註冊 OverrideMetadata
的實例。
然後,BeanFactoryPostProcessor
將使用該資訊來更改上下文,註冊和替換每個中繼資料定義的 Bean 定義。
Spring TestContext Framework 現在提供兩種在測試中覆寫 Bean 的方法,而沒有意外副作用的風險。Bean 覆寫機制是可擴展的,例如,如果您喜歡使用 Mockito 以外的 Mock 函式庫,這可能會派上用場。
我們期待社群對此功能的意見回饋,包括對此第一個迭代版本的改進建議。
同時,祝您編碼愉快!