Spring provides the following TestExecutionListener implementations, which are registered by default, in exactly the following order:

  • ServletTestExecutionListener: Configures servlet API mock objects for the WebApplicationContext.

  • DirtiesContextBeforeModesTestExecutionListener: Handles the @DirtiesContext annotation for "before" modes.

  • ApplicationEventsTestExecutionListener: Provides support for ApplicationEvents.

  • DependencyInjectionTestExecutionListener: Provides dependency injection for the test instance.

  • DirtiesContextTestExecutionListener: Handles the @DirtiesContext annotation for after modes.

  • TransactionalTestExecutionListener: Provides transactional execution of tests with default rollback semantics.

  • SqlScriptsTestExecutionListener: Executes SQL scripts configured with the @Sql annotation.

  • EventPublishingTestExecutionListener: Publishes test execution events
    in ApplicationContext.

Registering implementations of TestExecutionListener

You can register TestExecutionListener implementations for a test class and its subclasses using the @TestExecutionListeners annotation. For details and examples, see the annotation support subsection and the annotation javadoc @TestExecutionListeners.

Automatic detection of default TestExecutionListener implementations

Registering TestExecutionListener implementations with the @TestExecutionListeners annotation is suitable for special listeners that are used in limited testing scenarios. However, registration can become difficult if a custom listener needs to be used across the entire test suite. This issue is addressed by supporting automatic detection of TestExecutionListener implementations by default through the SpringFactoriesLoader mechanism.

Specifically, the spring-test module declares all default TestExecutionListener implementations in the org.springframework.test.context.TestExecutionListener key in the file META-INF/spring.factories properties. Third-party frameworks and developers can add their own TestExecutionListener implementations to the default listener list in the same way via their own META-INF/spring.factories properties file.

Ordering TestExecutionListener

If the TestContext framework discovers default TestExecutionListener implementations through the above SpringFactoriesLoader mechanism, the created listener instances are sorted using the AnnotationAwareOrderComparator of their Spring, which respects the interface Ordered from Spring and the @Order annotation for ordering. AbstractTestExecutionListener and all default TestExecutionListener implementations provided by Spring implement Ordered with appropriate values. Therefore, third-party frameworks and developers should ensure that their default TestExecutionListener implementations register in the correct order by implementing Ordered or declaring the @Order annotation. See the javadoc on the getOrder() methods of the default TestExecutionListener implementations for more details on what values are assigned to each main listener.

Combining TestExecutionListener

implementations

If a custom listener TestExecutionListener is registered via the @TestExecutionListeners annotation, listeners are not registered by default. In most common testing scenarios, this effectively forces the developer to manually declare all default listeners in addition to any custom listeners. The following listing demonstrates this configuration style:

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

The difficulty with this approach is that it requires the developer to know exactly which listeners are registered by default. Moreover, the set of default listeners may change from version to version - for example, the SqlScriptsTestExecutionListener listener was introduced in Spring Framework 4.1, and the DirtiesContextBeforeModesTestExecutionListener listener was introduced in Spring Framework 4.2. Moreover, third-party frameworks such as Spring Boot and Spring Security register their own default TestExecutionListener implementations using the aforementioned auto-detection mechanism.

To avoid having to know and re-declare all default listeners, you can set the mergeMode attribute of the @TestExecutionListeners annotation to MergeMode.MERGE_WITH_DEFAULTS. MERGE_WITH_DEFAULTS specifies that locally declared listeners should be merged with the default listeners. The merge algorithm ensures that duplicates are removed from the list and the resulting set of merged listeners is sorted according to the semantics of AnnotationAwareOrderComparator, as described in the "Ordering TestExecutionListener" implementations section. If a listener implements Ordered or is marked with the @Order annotation, it can influence the position in which it is combined with default listeners. Otherwise, locally declared listeners are added to the default listener list when merged.

For example, if the MyCustomTestExecutionListener class in the previous example configured its order value (for example, 500) to be less than the order value ServletTestExecutionListener (which is 1000), then MyCustomTestExecutionListener can be automatically combined with a list of default values before ServletTestExecutionListener, and the previous the example can be replaced by the following:

Java
@ContextConfiguration
@TestExecutionListeners(
    listeners = MyCustomTestExecutionListener.class,
    mergeMode = MERGE_WITH_DEFAULTS
)
class MyTest {
    // class body...
}
Kotlin
@ContextConfiguration
@TestExecutionListeners(
        listeners = [MyCustomTestExecutionListener::class],
        mergeMode = MERGE_WITH_DEFAULTS
)
class MyTest {
    // class body...
}