@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 配置它们。 |