You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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来替换掉生产环境中的Instance bean,这样被测类拿到的就是咱们的mock对象
  • 必须模拟Instance的核心方法(比如iterator()、get()),不然调用的时候会抛出空指针或者默认的mock行为(返回null)
  • 每个服务mock的行为要提前配置好,确保测试逻辑符合预期

备注:内容来源于stack exchange,提问作者nck

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.17 10:04:37