Quarkus响应式数据库操作测试报错:No current Vertx context found
问题原因
你遇到的No current Vertx context found异常,核心原因是**@InjectSpy替换了Quarkus生成的CDI代理实例**:
- Quarkus的CDI代理会自动处理Vertx上下文的传播,确保反应式数据库操作(比如Panache的
find())在正确的Vertx Event Loop/Worker上下文中执行。 - 当使用
@InjectSpy时,Mockito会直接创建一个Spy对象替换原有的CDI代理,直接调用这个Spy对象的方法时,没有触发Quarkus的上下文初始化逻辑,导致数据库操作找不到所需的Vertx上下文。
解决方案
针对这个问题,有两种可靠的解决方式:
方式1:保留CDI代理,手动创建Spy
放弃@InjectSpy,改用@Inject获取原生CDI代理实例,再用Mockito手动包装成Spy。这样既保留了Quarkus的上下文管理,又能实现Spy的功能:
@QuarkusTest class MyServiceTest { @Inject MyService myService; private MyService spyService; @BeforeEach void setUp() { // 基于CDI代理创建Spy,上下文会正常传播 spyService = Mockito.spy(myService); } @Test void testDatabaseOperation() { spyService.doSomeDatabaseOperation() .invoke(i -> Assertions.assertEquals(0, i.size())) .subscribe().withSubscriber(UniAssertSubscriber.create()) .assertCompleted(); } }
方式2:强制在Vertx上下文中执行测试方法
如果必须使用@InjectSpy,可以通过Quarkus提供的@RunOnVertxContext注解,强制测试方法在Vertx上下文中执行,确保数据库操作能找到上下文:
@QuarkusTest class MyServiceTest { @InjectSpy MyService myService; @Test @RunOnVertxContext void testDatabaseOperation() { myService.doSomeDatabaseOperation() .invoke(i -> Assertions.assertEquals(0, i.size())) .subscribe().withSubscriber(UniAssertSubscriber.create()) .assertCompleted(); } }
或者手动通过Vertx实例触发上下文执行:
@QuarkusTest class MyServiceTest { @InjectSpy MyService myService; @Inject Vertx vertx; @Test void testDatabaseOperation() { // 手动在Vertx上下文中执行测试逻辑 vertx.runOnContext(v -> { myService.doSomeDatabaseOperation() .invoke(i -> Assertions.assertEquals(0, i.size())) .subscribe().withSubscriber(UniAssertSubscriber.create()) .assertCompleted(); }); } }
内容的提问来源于stack exchange,提问作者Marian Klühspies
相关产品推荐
相关产品推荐

