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
实现
使用 @TestExecutionListeners
注册 TestExecutionListener
实现适用于在有限测试场景中使用的自定义监听器。但是,如果自定义监听器需要在整个测试套件中使用,则可能会变得很麻烦。通过 SpringFactoriesLoader
机制支持自动发现默认 TestExecutionListener
实现,解决了此问题。
例如,spring-test
模块在其 META-INF/spring.factories
属性文件 中的 org.springframework.test.context.TestExecutionListener
键下声明了所有核心默认 TestExecutionListener
实现。第三方框架和开发者可以通过其自身的 spring.factories
文件以相同的方式将他们自己的 TestExecutionListener
实现贡献到默认监听器列表中。
排序 TestExecutionListener
实现
当 TestContext 框架通过 上述 SpringFactoriesLoader
机制发现默认 TestExecutionListener
实现时,实例化的监听器将使用 Spring 的 AnnotationAwareOrderComparator
进行排序,该排序器会遵循 Spring 的 Ordered
接口和 @Order
注解进行排序。AbstractTestExecutionListener
和 Spring 提供的所有默认 TestExecutionListener
实现都实现了 Ordered
,并具有适当的值。因此,第三方框架和开发者应该确保他们的默认 TestExecutionListener
实现通过实现 Ordered
或声明 @Order
以正确的顺序注册。有关为每个核心监听器分配了哪些值的详细信息,请参阅核心默认 TestExecutionListener
实现的 getOrder()
方法的 javadoc。
合并 TestExecutionListener
实现
如果通过 @TestExecutionListeners
注册了自定义 TestExecutionListener
,则不会注册默认监听器。在大多数常见的测试场景中,这实际上迫使开发者除了任何自定义监听器之外,还要手动声明所有默认监听器。以下清单演示了这种配置风格
-
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 这样的第三方框架通过使用前面提到的 自动发现机制 注册它们自己的默认 TestExecutionListener
实现。
为了避免必须了解和重新声明所有默认监听器,您可以将 @TestExecutionListeners
的 mergeMode
属性设置为 MergeMode.MERGE_WITH_DEFAULTS
。MERGE_WITH_DEFAULTS
表示本地声明的监听器应该与默认监听器合并。合并算法确保从列表中删除重复项,并且合并后的监听器集按 AnnotationAwareOrderComparator
的语义排序,如 排序 TestExecutionListener
实现 中所述。如果监听器实现了 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...
}