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

Quarkus RestClient多@Consumes方法无法Mock的解决办法求助

解决Quarkus @RestClient Mock多@Consumes值的报错问题

你遇到的问题是Quarkus的@InjectMock在处理生成的RestClient接口时,因方法带有多个@Consumes值报错——这是因为Quarkus的Mock客户端生成逻辑不支持MicroProfile Rest Client方法配置多种消费类型,但你又无法修改生成的代码或OpenAPI规范。

以下是几个无需修改生成代码的解决方案:

方案一:手动实现Mock类并通过CDI替代

创建一个实现目标RestClient接口的Mock类,用CDI的@Alternative和@Priority注解让测试环境优先使用这个Mock实现:

@Alternative
@Priority(1)
@ApplicationScoped
public class DestinationsApiMock implements DestinationsApi {

    @Override
    public DestinationPatch destinationsPartialUpdate(Integer id, PatchedDestinationPatchRequest patchedDestinationPatchRequest) {
        // 自定义Mock逻辑,比如返回预设对象或抛出指定异常
        DestinationPatch mockResult = new DestinationPatch();
        // 可根据参数动态设置返回值
        return mockResult;
    }
}

测试类中直接注入原RestClient接口即可,Quarkus会自动使用你定义的Mock实现:

@QuarkusTest
class DestinationServiceTest {

    @Inject
    DestinationService service;

    @Inject
    DestinationsApi apiMock; // 此处注入的是自定义Mock实现

    @Test
    void testPartialUpdate() {
        // 直接使用apiMock验证或调整行为
    }
}

方案二:用Mockito手动创建Mock实例并注入

绕过Quarkus的@InjectMock自动生成逻辑,直接用Mockito创建Mock实例,再通过Setter或反射注入到业务服务中:

@QuarkusTest
class DestinationServiceTest {

    @Inject
    DestinationService service;

    DestinationsApi apiMock;

    @BeforeEach
    void setUp() {
        // 手动创建Mock实例
        apiMock = Mockito.mock(DestinationsApi.class);
        
        // 方式1:如果业务服务有Setter方法
        service.setDestinationsApi(apiMock);
        
        // 方式2:无Setter时用反射注入私有字段
        /*
        try {
            Field apiField = DestinationService.class.getDeclaredField("destinationsApi");
            apiField.setAccessible(true);
            apiField.set(service, apiMock);
        } catch (NoSuchFieldException | IllegalAccessException e) {
            throw new RuntimeException("注入Mock失败", e);
        }
        */
    }

    @Test
    void testPartialUpdate() {
        // 配置Mock行为
        DestinationPatch mockResponse = new DestinationPatch();
        Mockito.when(apiMock.destinationsPartialUpdate(Mockito.anyInt(), Mockito.any(PatchedDestinationPatchRequest.class)))
                .thenReturn(mockResponse);
        
        // 调用业务服务方法测试
        DestinationPatch result = service.someMethodThatCallsApi(1, new PatchedDestinationPatchRequest());
        
        // 验证Mock调用
        Mockito.verify(apiMock).destinationsPartialUpdate(1, Mockito.any());
    }
}

方案三:自定义CDI生产者复用Mock逻辑

如果需要在多个测试中复用Mock逻辑,可以创建一个CDI生产者,在测试环境提供预设的Mock实例:

@ApplicationScoped
public class DestinationsApiMockProducer {

    @Produces
    @RestClient
    @Alternative
    @Priority(1)
    public DestinationsApi produceMock() {
        DestinationsApi mock = Mockito.mock(DestinationsApi.class);
        // 预设通用Mock行为
        return mock;
    }
}

测试类中直接注入DestinationsApi即可使用该Mock实例,后续可在测试方法中动态调整Mock行为。


内容的提问来源于stack exchange,提问作者Ractoc

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 20:17:15