RESTMock源码解析:核心组件RESTMockServer和RequestMatchers工作原理
【免费下载链接】RESTMockHTTP Server for Android Instrumentation tests项目地址: https://gitcode.com/gh_mirrors/re/RESTMock
想要为Android应用编写可靠的单元测试和集成测试?RESTMock是一个强大的HTTP服务器模拟库,专门为Android Instrumentation测试设计!😊 作为基于Square的MockWebServer构建的库,RESTMock让API模拟变得简单直观。本文将深入解析RESTMock的核心组件——RESTMockServer和RequestMatchers的工作原理,帮助开发者更好地理解和使用这个优秀的测试工具。
🚀 RESTMockServer:HTTP模拟服务器的核心大脑
RESTMockServer是整个库的核心组件,负责管理HTTP请求的匹配和响应。它基于Square的MockWebServer构建,提供了一个简洁的API来定义请求-响应映射。
服务器初始化与配置
在core/src/main/java/io/appflate/restmock/RESTMockServer.java中,RESTMockServer使用静态方法进行初始化:
public synchronized static void init(RESTMockFileParser restMockFileParser, RESTMockLogger logger, RESTMockOptions restMockOptions) throws IOException { if (RESTMockServer.mockWebServer != null) { RESTMockServer.shutdown(); } RESTMockServer.mockWebServer = new MockWebServer(); if (logger != null) { RESTMockServer.logger = logger; } setUpHttps(restMockOptions); RESTMockServer.getLogger().log("## Starting RESTMock server..."); RESTMockServer.dispatcher = new MatchableCallsRequestDispatcher(); RESTMockServer.mockWebServer.setDispatcher(dispatcher); RESTMockServer.mockWebServer.start(); RESTMockServer.serverBaseUrl = mockWebServer.url("/").toString(); RequestsVerifier.init(dispatcher); RESTMockServer.RESTMockFileParser = restMockFileParser; RESTMockServer.getLogger().log("## RESTMock successfully started!\turl: " + RESTMockServer.serverBaseUrl); }初始化过程包括:
- 创建MockWebServer实例
- 配置HTTPS(如果需要)
- 设置请求分发器(MatchableCallsRequestDispatcher)
- 启动服务器并获取基础URL
- 初始化请求验证器
请求匹配API设计
RESTMockServer提供了简洁的API来定义HTTP请求的匹配规则:
// GET请求匹配 RESTMockServer.whenGET(pathContains("users/andrzejchm")) .thenReturnFile(200, "users/andrzejchm.json"); // POST请求匹配 RESTMockServer.whenPOST(pathStartsWith("api/login")) .thenReturnString(200, "{\"token\":\"abc123\"}"); // 自定义请求匹配 RESTMockServer.whenRequested(allOf(isPUT(), pathEndsWith("/profile"))) .thenReturnEmpty(204);在core/src/main/java/io/appflate/restmock/RESTMockServer.java中,这些辅助方法实际上都是whenRequested方法的包装:
public static MatchableCall whenGET(Matcher<RecordedRequest> requestMatcher) { return RESTMockServer.whenRequested(allOf(isGET(), requestMatcher)); }🎯 RequestMatchers:灵活的路由匹配引擎
RequestMatchers是RESTMock的另一个核心组件,位于core/src/main/java/io/appflate/restmock/utils/RequestMatchers.java。它提供了丰富的HTTP请求匹配器,让开发者能够精确控制哪些请求应该被模拟。
基础路径匹配器
// 路径包含特定字符串 pathContains("users") // 匹配 /api/users, /users/list, /admin/users // 路径以特定字符串结尾 pathEndsWith("/profile") // 匹配 /users/123/profile, /api/user/profile // 路径以特定字符串开头 pathStartsWith("/api/v1") // 匹配 /api/v1/users, /api/v1/login // 正则表达式匹配 pathMatchesRegex("/users/\\d+/profile") // 匹配 /users/123/profile高级查询参数匹配
RequestMatchers还支持复杂的查询参数匹配:
// 检查是否包含查询参数 hasQueryParameters() // 匹配任何包含查询参数的请求 // 检查是否包含特定查询参数名 hasQueryParameterNames("page", "limit") // 匹配 ?page=1&limit=10 // 精确匹配查询参数 hasExactQueryParameters( new QueryParam("page", "1"), new QueryParam("sort", "desc") ) // 精确匹配 ?page=1&sort=descHTTP方法匹配器
isGET() // 匹配GET请求 isPOST() // 匹配POST请求 isPUT() // 匹配PUT请求 isPATCH() // 匹配PATCH请求 isDELETE() // 匹配DELETE请求 isHEAD() // 匹配HEAD请求🔧 MatchableCallsRequestDispatcher:智能请求分发器
在core/src/main/java/io/appflate/restmock/MatchableCallsRequestDispatcher.java中,这个分发器负责处理所有传入的HTTP请求:
@Override public MockResponse dispatch(RecordedRequest recordedRequest) throws InterruptedException { requestsHistory.add(recordedRequest); RESTMockServer.getLogger().log("-> New Request:\t" + recordedRequest); List<MatchableCall> matchedCalls = getMatchedRequests(recordedRequest); if (matchedCalls.size() == 1) { return onOneResponseMatched(recordedRequest, matchedCalls); } else if (matchedCalls.size() > 1) { return onTooManyResponsesMatched(recordedRequest, matchedCalls); } else { return onNoResponsesMatched(recordedRequest); } }分发器的工作流程:
- 记录请求历史:将所有请求保存到历史记录中
- 查找匹配的响应:遍历所有已注册的MatchableCall
- 处理匹配结果:
- 1个匹配:返回对应的响应
- 多个匹配:返回错误(配置冲突)
- 0个匹配:返回"未模拟"错误
📊 MatchableCall:响应链管理
MatchableCall类(位于core/src/main/java/io/appflate/restmock/MatchableCall.java)负责管理响应链和延迟设置:
响应链配置
// 链式响应 RESTMockServer.whenGET(pathEndsWith("users")) .thenReturnString("first response") .thenReturnFile("users.json") .thenReturnEmpty(404); // 可变参数响应 RESTMockServer.whenGET(pathEndsWith("products")) .thenReturnString("response1", "response2", "response3");延迟控制
// 响应体延迟 RESTMockServer.whenGET(pathEndsWith("slow-api")) .thenReturnString("data") .delayBody(TimeUnit.SECONDS, 5, 10, 15); // 响应头延迟 RESTMockServer.whenGET(pathEndsWith("api")) .thenReturnString("result") .delayHeaders(TimeUnit.SECONDS, 2);🛠️ 自定义RequestMatcher实现
开发者可以轻松创建自定义的RequestMatcher来满足特定需求:
public class CustomRequestMatcher extends RequestMatcher { public CustomRequestMatcher() { super("Custom matcher for specific use case"); } @Override protected boolean matchesSafely(RecordedRequest item) { // 自定义匹配逻辑 return item.getPath().contains("special") && item.getMethod().equals("POST") && item.getHeader("X-Custom-Header") != null; } } // 使用自定义匹配器 RESTMockServer.whenRequested(new CustomRequestMatcher()) .thenReturnString(200, "Custom response");🔍 请求验证机制
RESTMock还提供了强大的请求验证功能:
// 验证请求是否被调用 RequestsVerifier.verifyGET(pathEndsWith("users")).invoked(); // 验证调用次数 RequestsVerifier.verifyGET(pathEndsWith("users")).exactly(2); // 验证最少调用次数 RequestsVerifier.verifyGET(pathEndsWith("users")).atLeast(1); // 验证从未调用 RequestsVerifier.verifyGET(pathEndsWith("users")).never();💡 最佳实践与性能优化
1.按测试用例重置模拟
@Before public void setUp() { RESTMockServer.reset(); // 清理所有模拟配置 }2.使用文件响应提高可维护性
// 将响应数据存储在文件中 RESTMockServer.whenGET(pathContains("users")) .thenReturnFile(200, "responses/users.json");3.组合使用匹配器
// 组合多个匹配条件 RESTMockServer.whenRequested( allOf( isPOST(), pathStartsWith("/api"), hasHeaderNames("Authorization", "Content-Type") ) ).thenReturnString(201, "Created");4.动态响应生成
RESTMockServer.whenGET(pathContains("dynamic")) .thenAnswer(new MockAnswer() { @Override public MockResponse answer(RecordedRequest request) { String query = request.getPath().split("\\?")[1]; return new MockResponse() .setBody("Processed: " + query) .setResponseCode(200); } });🎯 总结
RESTMock通过精心设计的组件架构,为Android Instrumentation测试提供了强大的HTTP模拟能力:
- RESTMockServer:作为中心控制器,管理服务器生命周期和请求分发
- RequestMatchers:提供灵活的请求匹配机制,支持各种HTTP特征匹配
- MatchableCallsRequestDispatcher:智能分发请求到正确的响应处理器
- MatchableCall:管理响应链和延迟配置
这种架构设计使得RESTMock既强大又灵活,能够满足从简单到复杂的各种测试场景需求。无论是基本的API模拟,还是复杂的请求验证和延迟测试,RESTMock都能提供简洁而强大的解决方案。
通过深入理解这些核心组件的工作原理,开发者可以更有效地使用RESTMock,编写出更可靠、更健壮的Android应用测试用例。🚀
【免费下载链接】RESTMockHTTP Server for Android Instrumentation tests项目地址: https://gitcode.com/gh_mirrors/re/RESTMock
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考