@MockitoBean
和 @MockitoSpyBean
@MockitoBean
和 @MockitoSpyBean
註解可用於測試類中,以將測試的 ApplicationContext
中的 Bean 分別覆蓋為 Mockito 的 mock 或 spy。在後一種情況下,會捕獲原始 Bean 的早期例項並由 spy 進行包裝。
這些註解可以透過以下方式應用:
-
在測試類或其任何超類中的非靜態欄位上。
-
在
@Nested
測試類的封閉類中的非靜態欄位上,或在@Nested
測試類之上的型別層級或封閉類層級中的任何類中。 -
在測試類或測試類之上的型別層級中的任何超類或實現的介面的型別級別上。
-
在
@Nested
測試類的封閉類的型別級別上,或在@Nested
測試類之上的型別層級或封閉類層級中的任何類或介面上。
當在欄位上宣告 @MockitoBean
或 @MockitoSpyBean
時,要 mock 或 spy 的 Bean 會從被註解欄位的型別推斷出來。如果在 ApplicationContext
中存在多個候選,可以在欄位上宣告 @Qualifier
註解以幫助消除歧義。如果沒有 @Qualifier
註解,被註解欄位的名稱將用作 回退限定符。或者,你可以透過在註解中設定 value
或 name
屬性來顯式指定要 mock 或 spy 的 Bean 名稱。
當在型別級別宣告 @MockitoBean
或 @MockitoSpyBean
時,要 mock 或 spy 的 Bean 型別(或多個 Bean 型別)必須透過註解中的 types
屬性提供 – 例如,@MockitoBean(types = {OrderService.class, UserService.class})
。如果在 ApplicationContext
中存在多個候選,你可以透過設定 name
屬性來顯式指定要 mock 或 spy 的 Bean 名稱。但是請注意,如果配置了顯式的 Bean name
,則 types
屬性必須只包含一個型別 – 例如,@MockitoBean(name = "ps1", types = PrintingService.class)
。
為了支援 mock 配置的重用,@MockitoBean
和 @MockitoSpyBean
可用作元註解來建立自定義的 組合註解 – 例如,在一個註解中定義通用的 mock 或 spy 配置,該註解可以在整個測試套件中重複使用。@MockitoBean
和 @MockitoSpyBean
也可以在型別級別用作可重複註解 — 例如,按名稱 mock 或 spy 多個 Bean。
限定符,包括欄位的名稱,用於確定是否需要建立單獨的 |
將 更多詳細資訊和示例請參閱帶有 Bean 覆蓋的上下文層級結構。 |
每個註解還定義了 Mockito 特有的屬性來微調 mocking 行為。
@MockitoBean
註解使用用於Bean 覆蓋的 REPLACE_OR_CREATE
策略。如果對應的 Bean 不存在,將建立一個新的 Bean。但是,你可以透過將 enforceOverride
屬性設定為 true
來切換到 REPLACE
策略 – 例如,@MockitoBean(enforceOverride = true)
。
@MockitoSpyBean
註解使用WRAP
策略,並且原始例項會被包裝到 Mockito spy 中。此策略要求恰好存在一個候選 Bean。
只有 singleton Bean 可以被覆蓋。任何嘗試覆蓋非 singleton Bean 的操作都將導致異常。 當使用 當使用 |
因此,這些欄位可以是 |
@MockitoBean
示例
以下示例展示瞭如何使用 @MockitoBean
註解的預設行為。
-
Java
@SpringJUnitConfig(TestConfig.class)
class BeanOverrideTests {
@MockitoBean (1)
CustomService customService;
// tests...
}
1 | 使用 Mockito mock 替換型別為 CustomService 的 Bean。 |
在上面的示例中,我們正在為 CustomService
建立 mock。如果存在該型別的多個 Bean,則考慮名稱為 customService
的 Bean。否則,測試將失敗,您需要提供某種限定符來標識要覆蓋哪個 CustomService
Bean。如果不存在這樣的 Bean,將建立一個具有自動生成 Bean 名稱的 Bean。
以下示例使用按名稱查詢,而不是按型別查詢。如果不存在名稱為 service
的 Bean,則建立一個新的。
-
Java
@SpringJUnitConfig(TestConfig.class)
class BeanOverrideTests {
@MockitoBean("service") (1)
CustomService customService;
// tests...
}
1 | 使用 Mockito mock 替換名稱為 service 的 Bean。 |
以下 @SharedMocks
註解註冊了兩個按型別和一按名稱的 mock。
-
Java
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@MockitoBean(types = {OrderService.class, UserService.class}) (1)
@MockitoBean(name = "ps1", types = PrintingService.class) (2)
public @interface SharedMocks {
}
1 | 註冊 OrderService 和 UserService 型別的 mock。 |
2 | 註冊名稱為 PrintingService 的 mock。 |
以下示例演示瞭如何在測試類中使用 @SharedMocks
。
-
Java
@SpringJUnitConfig(TestConfig.class)
@SharedMocks (1)
class BeanOverrideTests {
@Autowired OrderService orderService; (2)
@Autowired UserService userService; (2)
@Autowired PrintingService ps1; (2)
// Inject other components that rely on the mocks.
@Test
void testThatDependsOnMocks() {
// ...
}
}
1 | 透過自定義 @SharedMocks 註解註冊通用 mock。 |
2 | 可選地注入 mock 以進行 存根 或 驗證。 |
這些 mock 也可以注入到 @Configuration 類或 ApplicationContext 中其他與測試相關的元件中,以便使用 Mockito 的 stubbing API 配置它們。 |
@MockitoSpyBean
示例
以下示例展示瞭如何使用 @MockitoSpyBean
註解的預設行為。
-
Java
@SpringJUnitConfig(TestConfig.class)
class BeanOverrideTests {
@MockitoSpyBean (1)
CustomService customService;
// tests...
}
1 | 使用 Mockito spy 包裝型別為 CustomService 的 Bean。 |
在上面的示例中,我們正在包裝型別為 CustomService
的 Bean。如果存在該型別的多個 Bean,則考慮名稱為 customService
的 Bean。否則,測試將失敗,您需要提供某種限定符來標識要 spy 的 CustomService
Bean。
以下示例使用按名稱查詢,而不是按型別查詢。
-
Java
@SpringJUnitConfig(TestConfig.class)
class BeanOverrideTests {
@MockitoSpyBean("service") (1)
CustomService customService;
// tests...
}
1 | 使用 Mockito spy 包裝名稱為 service 的 Bean。 |
以下 @SharedSpies
註解註冊了兩個按型別和一按名稱的 spy。
-
Java
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@MockitoSpyBean(types = {OrderService.class, UserService.class}) (1)
@MockitoSpyBean(name = "ps1", types = PrintingService.class) (2)
public @interface SharedSpies {
}
1 | 註冊 OrderService 和 UserService 型別的 spy。 |
2 | 註冊名稱為 PrintingService 的 spy。 |
以下示例演示瞭如何在測試類中使用 @SharedSpies
。
-
Java
@SpringJUnitConfig(TestConfig.class)
@SharedSpies (1)
class BeanOverrideTests {
@Autowired OrderService orderService; (2)
@Autowired UserService userService; (2)
@Autowired PrintingService ps1; (2)
// Inject other components that rely on the spies.
@Test
void testThatDependsOnMocks() {
// ...
}
}
1 | 透過自定義 @SharedSpies 註解註冊通用 spy。 |
2 | 可選地注入 spy 以進行 存根 或 驗證。 |
這些 spy 也可以注入到 @Configuration 類或 ApplicationContext 中其他與測試相關的元件中,以便使用 Mockito 的 stubbing API 配置它們。 |