自 Spring Framework 5.3.3 以来,TestContext 框架提供了对记录 ApplicationContext 中发布的应用程序事件的支持,因此可以在测试中针对这些事件执行断言。在单个测试的执行过程中发布的所有事件都可以通过 ApplicationEvents API 获得,该 API 允许你将事件作为 java.util.Stream 进行处理。

    要在你的测试中使用 ApplicationEvents,请做以下工作:

    • 确保你的测试类有 @RecordApplicationEvents 的注解或元注解。

    • 确保 ApplicationEventsTestExecutionListener 被注册。但是请注意,ApplicationEventsTestExecutionListener 是默认注册的,只有当你通过 @TestExecutionListeners 的自定义配置不包括默认监听器时才需要手动注册。

    • 用 @Autowired 注解 ApplicationEvents 类型的字段,并在你的测试和生命周期方法中使用 ApplicationEvents 的实例(如 JUnit Jupiter 中的 @BeforeEach 和 @AfterEach 方法)。

    • 当使用 JUnit Jupiter 的 SpringExtension 时,你可以在测试或生命周期方法中声明一个 ApplicationEvents 类型的方法参数,作为测试类中 @Autowired 字段的替代。

    下面的测试类使用 JUnit Jupiter 的 SpringExtension 和 AssertJ 来断言在调用 Spring 管理的组件中的方法时发布的应用程序事件的类型。

    1. @SpringJUnitConfig(/* ... */)
    2. @RecordApplicationEvents // 用 @RecordApplicationEvents 来注解测试类。
    3. class OrderServiceTests {
    4. @Autowired
    5. OrderService orderService;
    6. // 注入当前测试的 ApplicationEvents 实例。
    7. @Autowired
    8. ApplicationEvents events;
    9. @Test
    10. void submitOrder() {
    11. // 调用 OrderService 中发布事件的方法
    12. orderService.submitOrder(new Order(/* ... */));
    13. // 使用 ApplicationEvents API 来计算有多少 OrderSubmitted 事件被发布。
    14. long numEvents = events.stream(OrderSubmitted.class).count();
    15. // 验证一个 OrderSubmitted 事件是否被发布了
    16. assertThat(numEvents).isEqualTo(1);
    17. }
    18. }

    关于 ApplicationEvents API 的进一步细节,请参见 ApplicationEvents javadoc