|
对于最新稳定版本,请使用 Spring Framework 7.0.6! |
TestExecutionListener 配置
Spring 提供了以下 TestExecutionListener 实现,这些实现默认按以下顺序注册:
-
ServletTestExecutionListener:为WebApplicationContext配置 Servlet API 的模拟对象。 -
DirtiesContextBeforeModesTestExecutionListener:处理“before”模式下的@DirtiesContext注解。 -
ApplicationEventsTestExecutionListener: 提供支持,用于ApplicationEvents。 -
DependencyInjectionTestExecutionListener:为测试实例提供依赖注入。 -
MicrometerObservationRegistryTestExecutionListener:提供对 Micrometer 的ObservationRegistry的支持。 -
DirtiesContextTestExecutionListener:处理“after”模式下的@DirtiesContext注解。 -
TransactionalTestExecutionListener:提供具有默认回滚语义的事务性测试执行。 -
SqlScriptsTestExecutionListener:执行通过@Sql注解配置的 SQL 脚本。 -
EventPublishingTestExecutionListener:将测试执行事件发布到测试的ApplicationContext中(参见测试执行事件)。
注册中TestExecutionListener实现
您可以使用 @TestExecutionListeners 注解为测试类、其子类及其嵌套类显式注册 TestExecutionListener 个实现。请参阅 注解支持 以及 @TestExecutionListeners 的 Javadoc 以获取详细信息和示例。
|
切换到默认的
TestExecutionListener 实现如果你扩展了一个带有
|
自动发现默认配置TestExecutionListener实现
使用 TestExecutionListener 注册 @TestExecutionListeners 实现类适用于在有限测试场景中使用的自定义监听器。然而,如果某个自定义监听器需要在整个测试套件中使用,这种方式就会变得繁琐。这一问题通过 TestExecutionListener 机制对默认 SpringFactoriesLoader 实现类的自动发现支持得以解决。
具体来说,spring-test 模块在其 TestExecutionListener 属性文件中,通过 org.springframework.test.context.TestExecutionListener 键声明了所有核心的默认 META-INF/spring.factories 实现。第三方框架和开发者也可以通过各自独立的 TestExecutionListener 属性文件,以相同的方式将自己的 META-INF/spring.factories 实现添加到默认监听器列表中。
排序TestExecutionListener实现
当 TestContext 框架通过前述的SpringFactoriesLoader机制发现默认TestExecutionListener实现时,实例化的监听器将使用 Spring 的AnnotationAwareOrderComparator进行排序,该排序机制遵循 Spring 的Ordered接口和@Order注解。AbstractTestExecutionListener以及 Spring 提供的所有默认TestExecutionListener实现都使用了适当的值实现了Ordered。因此,第三方框架和开发人员应确保其默认TestExecutionListener实现通过实现Ordered或声明@Order以正确的顺序注册。有关分配给每个核心监听器的具体值详情,请参阅核心默认TestExecutionListener实现的getOrder()方法的 Javadoc。
合并TestExecutionListener实现
如果通过 TestExecutionListener 注册了一个自定义的 @TestExecutionListeners,
则默认的监听器将不会被注册。在大多数常见的测试场景中,这实际上迫使开发者除了声明自定义监听器外,
还必须手动声明所有默认监听器。以下代码清单展示了这种配置方式:
-
Java
-
Kotlin
@ContextConfiguration
@TestExecutionListeners({
MyCustomTestExecutionListener.class,
ServletTestExecutionListener.class,
DirtiesContextBeforeModesTestExecutionListener.class,
DependencyInjectionTestExecutionListener.class,
DirtiesContextTestExecutionListener.class,
TransactionalTestExecutionListener.class,
SqlScriptsTestExecutionListener.class
})
class MyTest {
// class body...
}
@ContextConfiguration
@TestExecutionListeners(
MyCustomTestExecutionListener::class,
ServletTestExecutionListener::class,
DirtiesContextBeforeModesTestExecutionListener::class,
DependencyInjectionTestExecutionListener::class,
DirtiesContextTestExecutionListener::class,
TransactionalTestExecutionListener::class,
SqlScriptsTestExecutionListener::class
)
class MyTest {
// class body...
}
这种方法的难点在于,它要求开发人员确切地知道默认注册了哪些监听器。此外,默认监听器的集合可能会随版本发布而变化——例如,SqlScriptsTestExecutionListener 是在 Spring Framework 4.1 中引入的,而 DirtiesContextBeforeModesTestExecutionListener 则是在 Spring Framework 4.2 中引入的。此外,像 Spring Boot 和 Spring Security 这样的第三方框架也会通过上述自动发现机制注册它们自己的默认 #testcontext-tel-config-automatic-discovery 实现。
为避免必须知晓并重新声明所有默认监听器,您可以将 @TestExecutionListeners 的 mergeMode 属性设置为 MergeMode.MERGE_WITH_DEFAULTS。
MERGE_WITH_DEFAULTS 表示应将本地声明的监听器与默认监听器合并。合并算法确保从列表中移除重复项,并且根据 TestExecutionListener 实现的排序 中描述的 AnnotationAwareOrderComparator 语义对合并后的监听器集合进行排序。
如果监听器实现了 Ordered 或使用了 @Order 注解,则可以影响其与默认监听器合并时的位置。否则,在合并时,本地声明的监听器将被追加到默认监听器列表的末尾。
例如,如果上一个示例中的 MyCustomTestExecutionListener 类将其 order 值(例如 500)配置为小于 ServletTestExecutionListener 的顺序值(该值恰好为 1000),那么 MyCustomTestExecutionListener 就可以自动合并到默认监听器列表中,并排在 ServletTestExecutionListener 之前,此时前面的示例就可以替换为以下内容:
-
Java
-
Kotlin
@ContextConfiguration
@TestExecutionListeners(
listeners = MyCustomTestExecutionListener.class,
mergeMode = MERGE_WITH_DEFAULTS
)
class MyTest {
// class body...
}
@ContextConfiguration
@TestExecutionListeners(
listeners = [MyCustomTestExecutionListener::class],
mergeMode = MERGE_WITH_DEFAULTS
)
class MyTest {
// class body...
}