領先一步
VMware 提供培訓和認證,助您加速進步。
瞭解更多Spring Framework 6.2.0-M1 已釋出,其中包括解決一百多個問題的更改。其中包括 Spring 測試支援中的一系列新功能。
在這篇文章中,我想向您介紹其中一個新測試功能:Bean 覆蓋支援。
使用 Spring TestContext Framework,您可以使用註解驅動模型輕鬆驗證 Spring 應用程式在整合測試中的正確連線。
在單元測試中,依賴注入和 Spring 設計原則使您的程式碼對容器的依賴性降低,並使其更容易手動存根或模擬元件的依賴項,以便對其進行隔離測試。在整合測試中,這不那麼相關,因為測試旨在涵蓋元件的正確連線。儘管您可能會發現在整合測試中需要替換 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 進行基於 Mockito 的覆蓋第二個 bean 覆蓋實現基於 Mockito 庫。它帶有兩個註解:@MockitoBean 用於自動將目標單例 bean 替換為 mock,而 @MockitoSpyBean 則用於將 bean 包裝成 spy。
這些註解中的每一個都具有 Mockito 特定的屬性,以便進一步配置目標 bean 的模擬方式。這包括支援指定模擬如何在測試之間重置,如下例所示
@Configuration
class ProdConfiguration {
@Bean
MyService customService() {
return new ProdService();
}
}
@SpringJUnitConfig
class MyServiceIntegrationTests {
@MockitoSpyBean(reset = MockReset.NONE)
MyService customService;
@Test
void test() {
//...
}
}
在上面的示例中,spy 在測試之間將不會被重置。預設情況下,mock 和 spy 在測試方法執行之後重置。
請注意,為了監視一個 bean,首先必須存在一個被監視類的實際例項。Bean 覆蓋功能支援此特殊情況,並允許在例項化 bean 後從元資料建立覆蓋,此外還有更常見的替換 bean 定義的情況。
測試中新的 Bean 覆蓋支援以適用於測試類欄位的基於註解的模型形式提供。它是可擴充套件和可定製的,上面介紹的三個註解只是我們開箱即用提供的預設實現。
實現您自己的 Bean 覆蓋版本就像實現以下內容一樣簡單
@BeanOverride 元註解的註解,它定義要使用的 BeanOverrideProcessor。BeanOverrideProcessor 實現本身。OverrideMetadata 實現。Spring TestContext Framework 解析測試類,查詢任何帶有 @BeanOverride 元註解的欄位,並例項化相關的 BeanOverrideProcessor 以註冊 OverrideMetadata 例項。
然後,一個 BeanFactoryPostProcessor 將使用該資訊來更改上下文,根據每個元資料定義註冊和替換 bean 定義。
Spring TestContext Framework 現在提供了兩種在測試中覆蓋 bean 的方法,而沒有意外副作用的風險。bean 覆蓋機制是可擴充套件的,例如,如果您喜歡使用 Mockito 以外的模擬庫,這可能會派上用場。
我們期待社群對該功能的反饋,包括對首次迭代的改進建議。
同時,祝您編碼愉快!