如何在不启动全部依赖的情况下用Quarkus快速运行单元测试?
解决Quarkus单元测试启动慢的几种方案(无额外依赖)
针对你遇到的Quarkus单元测试启动耗时过长的问题,不用引入新依赖,用Quarkus自带的特性就能解决,下面是几个实用方案:
1. 使用轻量单元测试注解 @QuarkusUnitTest
@QuarkusTest 会启动完整的Quarkus应用,包含所有扩展和容器,而@QuarkusUnitTest 只初始化CDI容器的核心部分,不会启动HTTP服务器、数据库等外部依赖,启动速度快很多,完全满足纯业务类测试的需求。你的代码只需要替换注解即可,@InjectMock 和@Inject 仍然可以正常使用(Quarkus默认集成了Mockito):
import io.quarkus.test.junit.QuarkusUnitTest; import org.junit.jupiter.api.Test; import org.mockito.InjectMocks; import org.mockito.Mock; import static org.mockito.Mockito.*; @QuarkusUnitTest public class ExampleTest { @Mock private Dependency dep; @InjectMocks private MyCLass underTest; @Test public void testStuff() { underTest.doStuff(); verify(dep, times(1)).doMoreStuff(any()); } }
注:这里也可以继续用@InjectMock + @Inject的组合,和@Mock+@InjectMocks效果一致,选自己习惯的写法就行。
2. 手动初始化目标类,完全脱离CDI容器
如果你的测试类依赖简单,直接跳过Quarkus的容器初始化,用纯JUnit+Mockito手动创建实例和mock依赖,速度最快,完全没有容器启动开销:
import org.junit.jupiter.api.Test; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; import org.junit.jupiter.api.extension.ExtendWith; import static org.mockito.Mockito.*; @ExtendWith(MockitoExtension.class) public class ExampleTest { @Mock private Dependency dep; private MyCLass underTest; @org.junit.jupiter.api.BeforeEach void setUp() { underTest = new MyCLass(dep); } @Test public void testStuff() { underTest.doStuff(); verify(dep, times(1)).doMoreStuff(any()); } }
Quarkus项目默认已经包含JUnit 5和Mockito的依赖,所以不需要额外引入。
3. 自定义测试Profile,精简加载内容
如果必须使用@QuarkusTest(比如需要测试HTTP接口、数据库访问等部分依赖),可以通过@QuarkusTestProfile 自定义测试配置,排除不需要的扩展、Bean或者配置,减少启动的组件数量:
第一步:创建测试Profile类
import io.quarkus.test.junit.QuarkusTestProfile; import java.util.Set; public class MinimalTestProfile implements QuarkusTestProfile { // 排除不需要的扩展,比如如果不用数据库就排除jdbc相关扩展 @Override public Set<String> excludeModules() { return Set.of("quarkus-jdbc-postgresql", "quarkus-hibernate-orm"); } // 排除不需要的Bean @Override public Set<Class<?>> excludeBeans() { return Set.of(UnnecessaryService.class); } }
第二步:在测试类中使用该Profile
import io.quarkus.test.junit.QuarkusTest; import io.quarkus.test.junit.TestProfile; import org.junit.jupiter.api.Test; import org.mockito.InjectMock; import org.mockito.Inject; import static org.mockito.Mockito.*; @QuarkusTest @TestProfile(MinimalTestProfile.class) public class ExampleTest { @InjectMock private Dependency dep; @Inject private MyCLass underTest; @Test public void testStuff() { underTest.doStuff(); verify(dep, times(1)).doMoreStuff(any()); } }
根据你的测试场景选择合适的方案:如果只是测试纯业务逻辑,优先选方案1或2;如果需要部分Quarkus扩展支持,选方案3。
内容的提问来源于stack exchange,提问作者Mosd
相关产品推荐
相关产品推荐

