如何在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
相关产品推荐
相关产品推荐

