如何在Quarkus响应式测试的tearDown()方法中执行数据库操作?
解决JUnit tearDown中调用数据库清理方法的问题
针对你遇到的问题,这里提供几个可行的解决方案:
方案一:调整注解,使用工作线程执行阻塞操作
你之前的错误是因为@RunOnVertxContext强制方法在Vert.x事件循环线程执行,而事件循环线程不允许被阻塞。只保留@Blocking注解即可让Quarkus将方法调度到专门的工作线程池,安全执行阻塞操作:
@Inject FileRepository fileRepository; @Inject Mutiny.SessionFactory sessionFactory; @AfterEach @Blocking void tearDown() { sessionFactory.withSession(session -> fileRepository.deleteAll()) .await().indefinitely(); }
@Blocking注解会自动处理线程调度,避免事件循环被阻塞的错误。
方案二:使用异步非阻塞方式,返回Uni
Quarkus的JUnit扩展支持生命周期方法(如@AfterEach)返回Uni,它会自动等待异步操作完成,无需手动阻塞:
@Inject FileRepository fileRepository; @Inject Mutiny.SessionFactory sessionFactory; @AfterEach Uni<Void> tearDown() { // 如果需要事务,将withSession替换为withTransaction return sessionFactory.withSession(session -> fileRepository.deleteAll()) .replaceWithVoid(); }
这种方式更贴合Quarkus的异步编程模型,不需要依赖阻塞操作,性能也更好。
方案三:直接调用Repository的异步方法(如果是PanacheRepository)
如果你的FileRepository继承了Mutiny版本的PanacheRepository,那么deleteAll()方法本身就会自动管理Session和事务,无需手动注入SessionFactory:
@Inject FileRepository fileRepository; @AfterEach Uni<Void> tearDown() { return fileRepository.deleteAll(); }
或者用阻塞方式(同样需加@Blocking注解):
@Inject FileRepository fileRepository; @AfterEach @Blocking void tearDown() { fileRepository.deleteAll().await().indefinitely(); }
内容的提问来源于stack exchange,提问作者Marian Klühspies
相关产品推荐
相关产品推荐

