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

如何在MockWebServer的Dispatcher中结合响应入队实现混合逻辑?

整合MockWebServer的Dispatcher与顺序响应方案

实现思路

在自定义Dispatcher内部维护一个路径到响应队列的映射:对需要按顺序返回响应的接口(比如/query3),用队列存好预定义的响应序列;其他接口直接返回固定响应。这样既能保留Dispatcher不用逐个入队的高效性,又能支持重试场景的顺序响应需求。

代码实现

import okhttp3.mockwebserver.Dispatcher;
import okhttp3.mockwebserver.MockResponse;
import okhttp3.mockwebserver.RecordedRequest;
import java.util.Deque;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;

public class HybridDispatcher extends Dispatcher {
    // 存储需要按顺序返回响应的接口对应的响应队列
    private final Map<String, Deque<MockResponse>> sequentialResponseMap = new HashMap<>();

    public HybridDispatcher() {
        // 初始化/query3的响应序列:两次502,一次200
        Deque<MockResponse> query3Responses = new LinkedList<>();
        query3Responses.add(new MockResponse().setResponseCode(502));
        query3Responses.add(new MockResponse().setResponseCode(502));
        query3Responses.add(new MockResponse().setResponseCode(200).setBody("Success"));
        sequentialResponseMap.put("/query3", query3Responses);
    }

    @Override
    public MockResponse dispatch(RecordedRequest request) throws InterruptedException {
        String requestPath = request.getPath();
        
        // 优先处理有顺序响应要求的接口
        if (sequentialResponseMap.containsKey(requestPath)) {
            Deque<MockResponse> responseQueue = sequentialResponseMap.get(requestPath);
            // 队列不为空则取出队头响应,空队列返回默认404
            return responseQueue.isEmpty() ? new MockResponse().setResponseCode(404) : responseQueue.poll();
        }

        // 处理固定响应的接口
        switch (requestPath) {
            case "/query1":
                return new MockResponse().setResponseCode(200).setBody("Query1 Fixed Response");
            case "/query2":
                return new MockResponse().setResponseCode(200).setBody("Query2 Fixed Response");
            default:
                return new MockResponse().setResponseCode(404);
        }
    }

    // 可选:给测试提供重置指定接口响应队列的方法,方便复用测试实例
    public void resetSequentialQueue(String path, Deque<MockResponse> newQueue) {
        sequentialResponseMap.put(path, newQueue);
    }
}

测试使用示例

import okhttp3.mockwebserver.MockWebServer;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;

public class WebServerTests {
    private static MockWebServer mockServer;

    @BeforeAll
    static void initServer() throws Exception {
        mockServer = new MockWebServer();
        HybridDispatcher customDispatcher = new HybridDispatcher();
        mockServer.setDispatcher(customDispatcher);
        mockServer.start();
    }

    @Test
    void testRetryBackoff() {
        // 调用/query3的请求会依次拿到502、502、200,正好适配Retry.backoff(3, 10s)的重试逻辑
        // 这里编写你的重试测试代码
    }

    @Test
    void testFixedPathResponses() {
        // 调用/query1或/query2会一直返回固定响应,不用每次测试都手动入队
    }

    @AfterAll
    static void shutdownServer() throws Exception {
        mockServer.shutdown();
    }
}

方案优势

  • 只用一个MockWebServer实例,避免多实例启动的冗余问题
  • 固定响应接口无需重复入队,保持Dispatcher的高效性
  • 顺序响应通过内部队列实现,完全满足重试场景的多次请求顺序返回需求
  • 纯JDK+OkHttp原生API实现,不依赖第三方库

内容的提问来源于stack exchange,提问作者tintin.92

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 00:32:47