Test Execution Events

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

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.

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.

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).

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.

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.

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

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

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.