TestExecutionListener Configuration

Spring 提供了以下 TestExecutionListener 实现,这些实现已在默认情况下按如下顺序注册:

  • ServletTestExecutionListener:为 `WebApplicationContext`配置 Servlet API 仿真。

  • DirtiesContextBeforeModesTestExecutionListener:处理 `@DirtiesContext`注解的 "`before`"模式。

  • ApplicationEventsTestExecutionListener: Provides support for ApplicationEvents.

  • DependencyInjectionTestExecutionListener:为测试实例提供依赖注入。

  • MicrometerObservationRegistryTestExecutionListener:为 Micrometer 的`ObservationRegistry`提供支持。

  • DirtiesContextTestExecutionListener:处理 `@DirtiesContext`注解的 "`after`"模式。

  • CommonCachesTestExecutionListener:在测试的 `ApplicationContext`中清理资源缓存(如需)。

  • TransactionalTestExecutionListener:使用默认回滚语义提供事务测试执行。

  • SqlScriptsTestExecutionListener:运行使用 `@Sql`注解配置的 SQL 脚本。

  • EventPublishingTestExecutionListener:将测试执行事件发布到测试的 ApplicationContext(请参阅 Test Execution Events)。

Registering TestExecutionListener Implementations

您可以使用 @TestExecutionListeners 注释为测试类、其子类及其嵌套类明确注册 TestExecutionListener 实现。请参阅 annotation support 及https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/test/context/TestExecutionListeners.html[@TestExecutionListeners] 中的 javadoc 以了解详情和示例。

Switching to default TestExecutionListener implementations

如果您扩展了一个使用 @TestExecutionListeners 进行标注的类,并且需要切换为使用默认的侦听器集,则可以使用以下内容对您的类进行标注。

Java
// Switch to default listeners
@TestExecutionListeners(
	listeners = {},
	inheritListeners = false,
	mergeMode = MERGE_WITH_DEFAULTS)
class MyTest extends BaseTest {
	// class body...
}
Kotlin
// Switch to default listeners
@TestExecutionListeners(
	listeners = [],
	inheritListeners = false,
	mergeMode = MERGE_WITH_DEFAULTS)
class MyTest : BaseTest {
	// class body...
}

Automatic Discovery of Default TestExecutionListener Implementations

使用 @TestExecutionListeners 注册 TestExecutionListener 实现适用于在受限的测试场景中使用的自定义侦听器。但是,如果需要在整个测试套件中使用自定义侦听器,这样做可能很繁琐。这一问题可通过通过 SpringFactoriesLoader 机制自动发现用于的 TestExecutionListener 实现来解决。

例如,spring-test 模块在https://github.com/spring-projects/spring-framework/tree/main/spring-test/src/main/resources/META-INF/spring.factories[META-INF/spring.factories]属性文件中的 org.springframework.test.context.TestExecutionListener 键初始化中声明了所有核心默认 TestExecutionListener 实现。第三方框架和开发人员可以通过其自己的 spring.factories 文件以相同的方式将自己的 TestExecutionListener 实现添至默认侦听器列表。

Ordering TestExecutionListener Implementations

当 TestContext 框架通过aforementionedSpringFactoriesLoader 机制发现默认 TestExecutionListener 实现时,实例化侦听器将通过 Spring 的 AnnotationAwareOrderComparator 进行排序,AnnotationAwareOrderComparator 遵循 Spring 的 Ordered 接口和`@Order` 注释来进行排序。AbstractTestExecutionListener 和所有由 Spring 提供的默认`TestExecutionListener` 实现都使用适当的值实现 Ordered 。因此,第三方框架和开发人员应当确保他们的默认`TestExecutionListener` 实现通过实现 Ordered 或声明 @Order 按正确的顺序注册。有关分配给每个核心侦听器的值,请参见核心默认`TestExecutionListener` 实现的 getOrder() 方法的 javadoc。

Merging TestExecutionListener Implementations

如果通过 @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 中引入。此外,像 SpringBoot 和 Spring Security 这样的第三方框架会使用上述automatic discovery mechanism 来注册自己的默认`TestExecutionListener`实现。

为避免必须知道和重新声明所有默认侦听器,你可以将 @TestExecutionListenersmergeMode 属性设置为 MergeMode.MERGE_WITH_DEFAULTSMERGE_WITH_DEFAULTS 指示应该将本地声明的侦听器与默认侦听器合并。合并算法确保从列表中删除重复项,并确保所得合并的侦听器集根据 AnnotationAwareOrderComparator 的语义进行排序,如 xref:testing/testcontext-framework/tel-config.adoc#testcontext-tel-config-ordering[Ordering 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...
}