|
此版本仍在开发中,尚未稳定。如需最新的稳定版本,请使用 Spring Framework 7.0.6! |
@MockitoBean 和 @MockitoSpyBean
@MockitoBean 和
@MockitoSpyBean
可以在测试类中使用,以分别用Mockito的模拟对象或间谍对象覆盖测试的ApplicationContext中的bean。在后一种情况下,原始bean的早期实例将被捕获并由间谍对象包裹。
注解可以通过以下方式应用。
-
在测试类或其任何超类中的非静态字段上。
-
在一个非静态字段中,该字段位于封闭类中,用于一个
测试类0,或在类型层次结构或封闭类层次结构中位于测试类1之上的任何类中。 -
在测试类或测试类上方类型层次结构中的任何超类或实现的接口上,以类型级别定义。
-
在包围
@Nested测试类的类的类型级别上,或在@Nested测试类上方的类型层次结构或包围类层次结构中的任何类或接口上。
当在字段上声明@MockitoBean或@MockitoSpyBean时,要模拟或监视的bean将从注解字段的类型中推断。如果在ApplicationContext中存在多个候选者,可以在字段上声明一个@Qualifier注解来帮助消除歧义。在没有@Qualifier注解的情况下,将使用注解字段的名称作为回退限定符。或者,您可以通过在注解中设置value或name属性来显式指定要模拟或监视的bean名称。
当在类型级别声明为@MockitoBean或@MockitoSpyBean时,要模拟或监视的bean
(或beans)的类型必须通过注解中的types属性提供——
例如,@MockitoBean(types = {OrderService.class, UserService.class})。如果在ApplicationContext中存在多个候选对象,
您可以通过设置name属性来显式指定要模拟或监视的bean名称。但请注意,如果配置了明确的beanname,
则types属性必须包含单一类型——例如,@MockitoBean(name = "ps1", types = PrintingService.class)。
为了支持模拟配置的重用,@MockitoBean 和 @MockitoSpyBean 可以作为元注解来创建自定义的组合注解——例如,为了在一个注解中定义通用的模拟或间谍配置,该注解可以在整个测试套件中重复使用。@MockitoBean 和 @MockitoSpyBean 也可以作为类型级别的可重复注解使用——例如,通过名称模拟或监视多个bean。
|
限定符,包括字段的名称,用于确定是否需要创建独立的
|
|
使用 查看 带有bean覆盖的上下文层次结构 以获取更多详细信息和示例。 |
每个注解还定义了特定于 Mockito 的属性,以便微调模拟行为。
@MockitoBean 注解使用了 REPLACE_OR_CREATE
策略来覆盖bean。
如果对应的bean不存在,将创建一个新的bean。但是,您可以通过
将enforceOverride属性设置为true来切换到REPLACE策略——
例如,@MockitoBean(enforceOverride = true)。
@MockitoSpyBean 注解使用了 WRAP
策略,
原始实例被包裹在 Mockito 模拟对象中。此策略要求存在
恰好一个候选bean。
|
根据Mockito文档所述,有时使用 为了避免此类不希望的副作用,请考虑使用
|
|
仅单例bean可被覆盖。尝试覆盖非单例bean将导致异常。 在使用 在使用 |
|
因此,这些字段可以是 |
@MockitoBean 示例
以下示例展示了如何使用@0注解的默认行为。
-
Java
@SpringJUnitConfig(TestConfig.class)
class BeanOverrideTests {
@MockitoBean (1)
CustomService customService;
// tests...
}
| 1 | 将类型为CustomService的bean替换为Mockito模拟对象。 |
在上述示例中,我们为CustomService创建了一个模拟对象。如果存在多个该类型的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模拟对象。 |
以下 @SharedMocks 注解通过类型注册了两个模拟对象,并通过名称注册了一个模拟对象。
-
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 的模拟对象。 |
| 2 | 通过名称注册 PrintingService 个模拟对象。 |
以下演示了如何在测试类中使用@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 | 通过自定义的@MockBean注解注册通用的模拟对象。 |
| 2 | 可选择性地注入模拟对象以存根或验证它们。 |
模拟对象也可以被注入到@Configuration类或其他测试相关的
组件中,在ApplicationContext中,以便使用Mockito的存根API进行配置。 |
@MockitoSpyBean 示例
以下示例展示了如何使用@0注解的默认行为。
-
Java
@SpringJUnitConfig(TestConfig.class)
class BeanOverrideTests {
@MockitoSpyBean (1)
CustomService customService;
// tests...
}
| 1 | 使用Mockito的spy包装类型为CustomService的bean。 |
在上述示例中,我们将类型为CustomService的bean进行了包装。如果存在多个该类型的bean,那么将考虑名为customService的bean。否则,测试将失败,您需要提供某种限定符来标识您想要监视的是CustomService个bean中的哪一个。
以下示例使用了按名称查找,而非按类型查找。
-
Java
@SpringJUnitConfig(TestConfig.class)
class BeanOverrideTests {
@MockitoSpyBean("service") (1)
CustomService customService;
// tests...
}
| 1 | 使用Mockito的spy功能包裹名为service的bean。 |
以下 @SharedSpies 注解通过类型注册了两个间谍对象和一个通过名称注册的间谍对象。
-
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 个间谍。 |
| 2 | 通过名称注册 PrintingService 个间谍。 |
以下演示了如何在测试类中使用@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 | 通过自定义的@Spy注解注册通用间谍。 |
| 2 | 可选择性地注入模拟对象以存根或验证它们。 |
间谍同样可以被注入到@Configuration类或其他与测试相关的
组件中,在ApplicationContext里,以便使用Mockito的存根API进行配置。 |