Since Spring Framework 5.3.3, the TestContext framework provides support for recording
application events published in the
ApplicationContext
so that assertions can be performed against those events within
tests. All events published during the execution of a single test are made available via
the ApplicationEvents
API which allows you to process the events as a
java.util.Stream
.
To use ApplicationEvents
in your tests, do the following.
-
Ensure that your test class is annotated or meta-annotated with
@RecordApplicationEvents
. -
Ensure that the
ApplicationEventsTestExecutionListener
is registered. Note, however, thatApplicationEventsTestExecutionListener
is registered by default and only needs to be manually registered if you have custom configuration via@TestExecutionListeners
that does not include the default listeners. -
Annotate a field of type
ApplicationEvents
with@Autowired
and use that instance ofApplicationEvents
in your test and lifecycle methods (such as@BeforeEach
and@AfterEach
methods in JUnit Jupiter).-
When using the SpringExtension for JUnit Jupiter, you may declare a method parameter of type
ApplicationEvents
in a test or lifecycle method as an alternative to an@Autowired
field in the test class.
-
The following test class uses the SpringExtension
for JUnit Jupiter and
AssertJ to assert the types of application events
published while invoking a method in a Spring-managed component:
-
Java
-
Kotlin
@SpringJUnitConfig(/* ... */)
@RecordApplicationEvents (1)
class OrderServiceTests {
@Autowired
OrderService orderService;
@Autowired
ApplicationEvents events; (2)
@Test
void submitOrder() {
// Invoke method in OrderService that publishes an event
orderService.submitOrder(new Order(/* ... */));
// Verify that an OrderSubmitted event was published
long numEvents = events.stream(OrderSubmitted.class).count(); (3)
assertThat(numEvents).isEqualTo(1);
}
}
1 | Annotate the test class with @RecordApplicationEvents . |
2 | Inject the ApplicationEvents instance for the current test. |
3 | Use the ApplicationEvents API to count how many OrderSubmitted events were published. |
@SpringJUnitConfig(/* ... */)
@RecordApplicationEvents (1)
class OrderServiceTests {
@Autowired
lateinit var orderService: OrderService
@Autowired
lateinit var events: ApplicationEvents (2)
@Test
fun submitOrder() {
// Invoke method in OrderService that publishes an event
orderService.submitOrder(Order(/* ... */))
// Verify that an OrderSubmitted event was published
val numEvents = events.stream(OrderSubmitted::class).count() (3)
assertThat(numEvents).isEqualTo(1)
}
}
1 | Annotate the test class with @RecordApplicationEvents . |
2 | Inject the ApplicationEvents instance for the current test. |
3 | Use the ApplicationEvents API to count how many OrderSubmitted events were published. |
1 | Annotate the test class with @RecordApplicationEvents . |
2 | Inject the ApplicationEvents instance for the current test. |
3 | Use the ApplicationEvents API to count how many OrderSubmitted events were published. |
1 | Annotate the test class with @RecordApplicationEvents . |
2 | Inject the ApplicationEvents instance for the current test. |
3 | Use the ApplicationEvents API to count how many OrderSubmitted events were published. |
See the
ApplicationEvents
javadoc for further details regarding the ApplicationEvents
API.