@MockitoBean 和 @MockitoSpyBean
@MockitoBean 和 @MockitoSpyBean 可用於測試類中,分別用 Mockito 的 mock 或 spy 替換測試的 ApplicationContext 中的 bean。在後一種情況下,原始 bean 的早期例項會被捕獲並由 spy 包裝。
註解可以透過以下方式應用。
-
在測試類或其任何超類的非靜態欄位上。
-
在
@Nested測試類的外層類的非靜態欄位上,或在@Nested測試類上方的型別層次結構或外層類層次結構中的任何類上。 -
在測試類或其任何超類或測試類上方的型別層次結構中實現的介面的型別級別上。
-
在
@Nested測試類的外層類的型別級別上,或在@Nested測試類上方的型別層次結構或外層類層次結構中的任何類或介面上。
當 @MockitoBean 或 @MockitoSpyBean 在欄位上宣告時,要 mock 或 spy 的 bean 會從註解欄位的型別中推斷出來。如果 ApplicationContext 中存在多個候選物件,可以在欄位上宣告 @Qualifier 註解以幫助消除歧義。在沒有 @Qualifier 註解的情況下,註解欄位的名稱將用作 fallback 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 註解使用 REPLACE_OR_CREATE bean 覆蓋策略。如果不存在相應的 bean,將建立一個新 bean。但是,您可以透過將 enforceOverride 屬性設定為 true 來切換到 REPLACE 策略,例如 @MockitoBean(enforceOverride = true)。
@MockitoSpyBean 註解使用 WRAP 策略,原始例項被包裝在一個 Mockito spy 中。此策略要求恰好存在一個候選 bean。
|
如 Mockito 文件中所述,有時使用 為避免此類不希望的副作用,請考慮使用 |
|
當使用 類似地,當使用 當使用 類似地,當使用 此外, |
|
因此,這些欄位可以是 |
@MockitoBean 示例
以下示例展示瞭如何使用 @MockitoBean 註解的預設行為。
-
Java
@SpringJUnitConfig(TestConfig.class)
class BeanOverrideTests {
@MockitoBean (1)
CustomService customService;
// tests...
}
| 1 | 將型別為 CustomService 的 bean 替換為 Mockito mock。 |
在上面的示例中,我們正在為 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 | 將名為 service 的 bean 替換為 Mockito mock。 |
以下 @SharedMocks 註解按型別註冊了兩個 mock,按名稱註冊了一個 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 以進行 stub 或 verify。 |
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,按名稱註冊了一個 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 以進行 stub 或 verify。 |
spy 也可以注入到 @Configuration 類或 ApplicationContext 中其他與測試相關的元件中,以便使用 Mockito 的 stubbing API 配置它們。 |