跳到主要内容

TestExecutionListener 配置

ChatGPT-4o 中英对照 TestExecutionListener Configuration TestExecutionListener Configuration

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

  • ServletTestExecutionListener:为 WebApplicationContext 配置 Servlet API 模拟对象。

  • DirtiesContextBeforeModesTestExecutionListener:处理“before”模式的 @DirtiesContext 注解。

  • ApplicationEventsTestExecutionListener:提供对应用事件的支持。

  • 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 实现

如果你扩展了一个带有 @TestExecutionListeners 注解的类,并且需要切换到使用默认的监听器集,你可以用以下注解标记你的类。

// 切换到默认监听器
@TestExecutionListeners(
listeners = {},
inheritListeners = false,
mergeMode = MERGE_WITH_DEFAULTS)
class MyTest extends BaseTest {
// class body...
}
java

默认 TestExecutionListener 实现的自动发现

通过使用 @TestExecutionListeners 注册 TestExecutionListener 实现适用于在有限的测试场景中使用的自定义监听器。然而,如果需要在整个测试套件中使用自定义监听器,这可能会变得麻烦。这个问题可以通过 SpringFactoriesLoader 机制支持自动发现默认的 TestExecutionListener 实现来解决。

例如,spring-test 模块在其 META-INF/spring.factories properties file 中,通过 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,则默认监听器不会被注册。在大多数常见的测试场景中,这实际上迫使开发人员在添加任何自定义监听器的同时手动声明所有默认监听器。以下示例演示了这种配置风格:

@ContextConfiguration
@TestExecutionListeners({
MyCustomTestExecutionListener.class,
ServletTestExecutionListener.class,
DirtiesContextBeforeModesTestExecutionListener.class,
DependencyInjectionTestExecutionListener.class,
DirtiesContextTestExecutionListener.class,
TransactionalTestExecutionListener.class,
SqlScriptsTestExecutionListener.class
})
class MyTest {
// class body...
}
java

这种方法的挑战在于,它要求开发人员确切知道默认注册了哪些监听器。此外,默认监听器的集合可能会随着版本的变化而变化——例如,SqlScriptsTestExecutionListener 是在 Spring Framework 4.1 中引入的,而 DirtiesContextBeforeModesTestExecutionListener 是在 Spring Framework 4.2 中引入的。此外,像 Spring Boot 和 Spring Security 这样的第三方框架通过使用前面提到的自动发现机制注册它们自己的默认 TestExecutionListener 实现。

为了避免需要了解和重新声明所有默认监听器,可以将 @TestExecutionListenersmergeMode 属性设置为 MergeMode.MERGE_WITH_DEFAULTSMERGE_WITH_DEFAULTS 表示本地声明的监听器应与默认监听器合并。合并算法确保从列表中移除重复项,并根据 AnnotationAwareOrderComparator 的语义对合并后的监听器集进行排序,如Ordering TestExecutionListener Implementations中所述。如果监听器实现了 Ordered 接口或被 @Order 注解标注,则可以影响其与默认监听器合并时的位置。否则,本地声明的监听器在合并时会附加到默认监听器列表中。

例如,如果前面例子中的 MyCustomTestExecutionListener 类将其 order 值配置为小于 ServletTestExecutionListener 的顺序值(例如,500 小于 1000),那么 MyCustomTestExecutionListener 就可以自动与默认列表合并,并排在 ServletTestExecutionListener 之前,之前的例子可以替换为以下内容:

@ContextConfiguration
@TestExecutionListeners(
listeners = MyCustomTestExecutionListener.class,
mergeMode = MERGE_WITH_DEFAULTS
)
class MyTest {
// class body...
}
java