如何在Quarkus中使用Mockito模拟Instance<T>类以测试同类型的多个服务?
如何在Quarkus中使用Mockito模拟Instance类以测试同类型的多个服务?
首先我得先理解你的场景:你原本是直接注入单个ServiceInterface实现类来用,现在应该是遇到了同接口多实现的情况,需要用Instance<ServiceInterface>来获取所有(或指定的)服务实例,这时候想在测试里用Mockito模拟这个Instance类对吧?
先把修改后的生产代码贴出来,比如你的GreetingResource改成用Instance注入:
@Path("/hello") public class GreetingResource { @Inject Instance<ServiceInterface> serviceInstances; @GET @Produces(MediaType.TEXT_PLAIN) public String hello() { StringBuilder stringBuilder = new StringBuilder(); // 遍历所有ServiceInterface实例 serviceInstances.forEach(service -> stringBuilder.append(service.getName()).append("; ")); return stringBuilder.toString().trim(); } }
接下来咱们说测试怎么写,首先得确保你的项目里加了Quarkus Mockito的测试依赖,Maven的话在pom.xml里加:
<dependency> <groupId>io.quarkus</groupId> <artifactId>quarkus-junit5-mockito</artifactId> <scope>test</scope> </dependency>
然后是测试类的写法,核心思路是模拟Instance对象,让它返回咱们预设好的服务mock实例:
import io.quarkus.test.junit.QuarkusTest; import org.junit.jupiter.api.Test; import org.mockito.InjectMock; import org.mockito.Mock; import javax.enterprise.inject.Instance; import java.util.Arrays; import static io.restassured.RestAssured.given; import static org.hamcrest.CoreMatchers.is; import static org.mockito.Mockito.when; @QuarkusTest public class GreetingResourceTest { // 用@InjectMock把这个mock的Instance注入到被测的GreetingResource里 @InjectMock Instance<ServiceInterface> mockServiceInstance; // 模拟两个ServiceInterface的实现类实例 @Mock ServiceInterface mockServiceA; @Mock ServiceInterface mockServiceB; @Test public void testHelloEndpoint() { // 先给每个mock服务配置好行为 when(mockServiceA.getName()).thenReturn("I am A"); when(mockServiceB.getName()).thenReturn("I am B"); // 关键步骤:让Instance的iterator()返回咱们的mock列表迭代器 when(mockServiceInstance.iterator()).thenReturn(Arrays.asList(mockServiceA, mockServiceB).iterator()); // 发起REST请求验证结果 given() .when().get("/hello") .then() .statusCode(200) .body(is("I am A; I am B")); } }
如果你的场景是用Instance获取单个可选实例(比如serviceInstance.get()),那就要调整mock的配置:
// 模拟实例可用 when(mockServiceInstance.isAvailable()).thenReturn(true); // 让get()返回指定的mock实例 when(mockServiceInstance.get()).thenReturn(mockServiceA);
这里有几个关键点要注意:
- 用
@InjectMock来替换掉生产环境中的Instancebean,这样被测类拿到的就是咱们的mock对象 - 必须模拟
Instance的核心方法(比如iterator()、get()),不然调用的时候会抛出空指针或者默认的mock行为(返回null) - 每个服务mock的行为要提前配置好,确保测试逻辑符合预期
备注:内容来源于stack exchange,提问作者nck
相关产品推荐
相关产品推荐

