Quarkus非全局Mock依赖注入测试报错排查与最优实现方案咨询
问题分析
- 你在
@BeforeEach中手动实例化的DummyReceiver未被Quarkus的CDI容器托管,CDI事件总线分发的DummyMessage只会被容器自动初始化的DummyReceiver实例消费,该容器实例注入的是真实的DummyDependency实现,你自行创建的mock实例不会收到任何调用,因此断言失败。 - 运行日志中两条
DummyReceiver创建记录也验证了该问题:第一条是你手动创建的、绑定了mock的实例,第二条是Quarkus容器启动时初始化的、绑定了真实实现代理的实例。 - 补充说明:你之前对Quarkus官方Mock机制的理解存在偏差,Quarkus的
@Mock/@MockBean是测试类级别隔离的,不同测试类的mock实例完全独立,不会出现所有测试共用同一个mock的情况。
修复方案
方案1:纯单元测试(无需启动Quarkus容器,执行速度最快)
不需要依赖CDI容器能力,直接调用业务方法测试即可:
import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import java.util.concurrent.TimeUnit; public class DummyReceiverTest { private DummyDependencyMock mock; private DummyReceiver receiver; @BeforeEach public void setup() { mock = new DummyDependencyMock(); receiver = new DummyReceiver(mock); } @Test public void test() throws Exception { String id = "123"; // 直接调用业务方法,不走CDI事件分发 receiver.onProcessScannerMessage(new DummyMessage(id)); String storedId = mock.ids.poll(1, TimeUnit.SECONDS); Assertions.assertEquals("123", storedId); } }
方案2:Quarkus集成测试(使用官方Mock机制,适合需要验证CDI事件等容器特性的场景)
首先引入Quarkus Mockito依赖:
<dependency> <groupId>io.quarkus</groupId> <artifactId>quarkus-junit5-mockito</artifactId> <scope>test</scope> </dependency>
改写测试类,使用@MockBean替换容器中的依赖实现:
import io.quarkus.test.junit.QuarkusTest; import io.quarkus.test.junit.mockito.MockBean; import java.util.concurrent.TimeUnit; import javax.enterprise.event.Event; import javax.inject.Inject; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; @QuarkusTest public class DummyReceiverTest { @Inject Event<DummyMessage> messageEvent; // 仅在当前测试类范围内,将容器中DummyDependencyInterface的实现替换为该mock实例 @MockBean DummyDependencyMock mock; @Test public void test() throws Exception { String id = "123"; messageEvent.fire(new DummyMessage(id)); String storedId = mock.ids.poll(1, TimeUnit.SECONDS); Assertions.assertEquals("123", storedId); } }
方案3:Mockito注解驱动单元测试(和你提供的示例方案逻辑一致)
无需启动Quarkus容器,通过Mockito注解自动注入mock:
import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; import static org.mockito.Mockito.verify; @ExtendWith(MockitoExtension.class) public class DummyReceiverTest { @Mock DummyDependencyInterface dependencyMock; @InjectMocks DummyReceiver receiver; @Test public void test() { String testId = "123"; receiver.onProcessScannerMessage(new DummyMessage(testId)); // 验证依赖方法被调用且参数符合预期 verify(dependencyMock).store(testId); } }
内容的提问来源于stack exchange,提问作者MikeElmwood
相关产品推荐
相关产品推荐

