TestExecutionListener
配置
Spring 提供以下默认注册的TestExecutionListener
实现,其顺序如下所示:
-
ServletTestExecutionListener
:为WebApplicationContext
配置 Servlet API 模拟。 -
DirtiesContextBeforeModesTestExecutionListener
:处理“before”模式下的@DirtiesContext
注解。 -
ApplicationEventsTestExecutionListener
:提供对ApplicationEvents
的支持。 -
BeanOverrideTestExecutionListener
:提供对测试中 Bean 的覆盖的支持。 -
DependencyInjectionTestExecutionListener
:为测试实例提供依赖注入。 -
MicrometerObservationRegistryTestExecutionListener
:提供对 Micrometer 的ObservationRegistry
的支持。 -
DirtiesContextTestExecutionListener
:处理“after”模式下的@DirtiesContext
注解。 -
CommonCachesTestExecutionListener
:如有必要,清除测试的ApplicationContext
中的资源缓存。 -
TransactionalTestExecutionListener
:提供具有默认回滚语义的事务测试执行。 -
SqlScriptsTestExecutionListener
:运行使用@Sql
注解配置的 SQL 脚本。 -
EventPublishingTestExecutionListener
:将测试执行事件发布到测试的ApplicationContext
(请参阅测试执行事件)。 -
MockitoResetTestExecutionListener
:重置由@MockitoBean
或@MockitoSpyBean
配置的模拟。
注册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...
}