Test Execution Events

Spring Framework 5.2 中引入的 EventPublishingTestExecutionListener 提供了一种替代方法来实现自定义 TestExecutionListener。测试的 ApplicationContext 中的组件可以监听 EventPublishingTestExecutionListener 发布的以下事件,每个事件对应于 TestExecutionListener API 中的方法。

The EventPublishingTestExecutionListener introduced in Spring Framework 5.2 offers an alternative approach to implementing a custom TestExecutionListener. Components in the test’s ApplicationContext can listen to the following events published by the EventPublishingTestExecutionListener, each of which corresponds to a method in the TestExecutionListener API.

  • BeforeTestClassEvent

  • PrepareTestInstanceEvent

  • BeforeTestMethodEvent

  • BeforeTestExecutionEvent

  • AfterTestExecutionEvent

  • AfterTestMethodEvent

  • AfterTestClassEvent

这些事件可以出于各种原因进行监听,例如重置模拟 bean 或跟踪测试执行。监听测试执行事件而不是实现自定义 TestExecutionListener 的一个优势在于,测试执行事件可以被测试 ApplicationContext 中注册的任何 Spring bean 监听,并且这些 bean 可以直接受益于依赖项注入和 ApplicationContext 的其他功能。相反,TestExecutionListener 不是 ApplicationContext 中的 bean。

These events may be consumed for various reasons, such as resetting mock beans or tracing test execution. One advantage of consuming test execution events rather than implementing a custom TestExecutionListener is that test execution events may be consumed by any Spring bean registered in the test ApplicationContext, and such beans may benefit directly from dependency injection and other features of the ApplicationContext. In contrast, a TestExecutionListener is not a bean in the ApplicationContext.

默认情况下会注册 EventPublishingTestExecutionListener;但是,它仅在 已经加载 ApplicationContext 时才发布事件。这防止了不必要地或过早地加载 ApplicationContext

The EventPublishingTestExecutionListener is registered by default; however, it only publishes events if the ApplicationContext has already been loaded. This prevents the ApplicationContext from being loaded unnecessarily or too early.

因此,在另一个 TestExecutionListener 加载 ApplicationContext 之后,才会发布 BeforeTestClassEvent。例如,对于注册的 TestExecutionListener 实现的默认设置,对于使用特定测试 ApplicationContext 的第一个测试类,不会发布 BeforeTestClassEvent,但会为同一测试套件中使用相同测试 ApplicationContext 的任何后续测试类发布 BeforeTestClassEvent,因为上下文已经在后续测试类运行时已经加载(只要上下文未通过 @DirtiesContext 或最大大小驱逐策略从 ContextCache 中删除)。

Consequently, a BeforeTestClassEvent will not be published until after the ApplicationContext has been loaded by another TestExecutionListener. For example, with the default set of TestExecutionListener implementations registered, a BeforeTestClassEvent will not be published for the first test class that uses a particular test ApplicationContext, but a BeforeTestClassEvent will be published for any subsequent test class in the same test suite that uses the same test ApplicationContext since the context will already have been loaded when subsequent test classes run (as long as the context has not been removed from the ContextCache via @DirtiesContext or the max-size eviction policy).

如果您希望为每个测试类始终发布 BeforeTestClassEvent,那么您需要注册一个 TestExecutionListenerbeforeTestClass 回调中加载 ApplicationContext,而且该 TestExecutionListener 必须在 EventPublishingTestExecutionListener 之前 注册。

If you wish to ensure that a BeforeTestClassEvent is always published for every test class, you need to register a TestExecutionListener that loads the ApplicationContext in the beforeTestClass callback, and that TestExecutionListener must be registered before the EventPublishingTestExecutionListener.

同样,如果使用 @DirtiesContext 从给定测试类中的最后一个测试方法后从上下文缓存中删除 ApplicationContext ,则不会为该测试类发布 AfterTestClassEvent

Similarly, if @DirtiesContext is used to remove the ApplicationContext from the context cache after the last test method in a given test class, the AfterTestClassEvent will not be published for that test class.

为了监听测试执行事件,Spring bean 可能会选择实现`org.springframework.context.ApplicationListener` 接口。或者,可以使用 @EventListener 对侦听器方法进行注释,并将其配置为侦听上述具体事件类型之一(见Annotation-based Event Listeners)。由于这种方法很流行,Spring 提供了以下专用的`@EventListener` 注释,以简化测试执行事件侦听器的注册。这些注释位于 `org.springframework.test.context.event.annotation`包中。

In order to listen to test execution events, a Spring bean may choose to implement the org.springframework.context.ApplicationListener interface. Alternatively, listener methods can be annotated with @EventListener and configured to listen to one of the particular event types listed above (see Annotation-based Event Listeners). Due to the popularity of this approach, Spring provides the following dedicated @EventListener annotations to simplify registration of test execution event listeners. These annotations reside in the org.springframework.test.context.event.annotation package.

  • @BeforeTestClass

  • @PrepareTestInstance

  • @BeforeTestMethod

  • @BeforeTestExecution

  • @AfterTestExecution

  • @AfterTestMethod

  • @AfterTestClass

Exception Handling

默认情况下,如果测试执行事件监听器在使用事件时抛出异常,则该异常将传播到正在使用的基础测试框架(例如 JUnit 或 TestNG)。例如,如果 BeforeTestMethodEvent 的使用导致异常,则相应的测试方法将因异常失败。相反,如果异步测试执行事件监听器抛出异常,则异常不会传播到基础测试框架。有关异步异常处理的更多详细信息,请参阅 @EventListener 的类级 javadoc。

By default, if a test execution event listener throws an exception while consuming an event, that exception will propagate to the underlying testing framework in use (such as JUnit or TestNG). For example, if the consumption of a BeforeTestMethodEvent results in an exception, the corresponding test method will fail as a result of the exception. In contrast, if an asynchronous test execution event listener throws an exception, the exception will not propagate to the underlying testing framework. For further details on asynchronous exception handling, consult the class-level javadoc for @EventListener.

Asynchronous Listeners

如果你希望某个特定的测试执行事件监听器异步处理事件,则可以使用 Spring 的 xref:integration/scheduling.adoc#scheduling-annotation-support-async[regular @Async 支持。有关详细信息,请查阅 @EventListener 的类级 javadoc。

If you want a particular test execution event listener to process events asynchronously, you can use Spring’s regular @Async support . For further details, consult the class-level javadoc for @EventListener.