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