为什么需要 Mock 适配器?测试痛点与架构思考
做 Android 接口测试,迟早会遇到一个很尴尬的场面:明明代码写好了,跑测试却得等后端接口就绪。我早些年就踩过这个坑,项目组每天因为联调时间吵得不可开交。今天就聊聊,为什么我们需要 Mock 适配器来解这个局。
测试应该尽早、独立运行,不依赖任何外部服务。Mock 适配器就是帮我们在本地模拟网络响应,让测试变得可控、可重复。
你肯定碰到过的测试痛点
咱们先列举几个真实现状。你在写单元测试时,是不是经常遇到下面这些情况?
- 接口没写好 —— 前端等后端接口,测试进度卡死。
- 网络不稳定 —— 跑一次测试,可能因为超时或断网而失败。
- 数据难造 —— 想测某个边界值,后端压根没提供这个数据。
- 测试太慢 —— 每次都要走真实 HTTP 请求,几秒甚至几十秒才出一轮结果。
- 副作用不可控 —— 比如测试一个「删除用户」接口,真的把数据库数据删掉了。
这些问题说白了,都因为我们的测试代码依赖了真实的外部服务。我有个项目经历过线上事故,测试环境覆盖不全,结果某个接口改了个字段名称,上线直接崩溃。嗯,从那以后我就下定决心,必须把 Mock 引入到测试体系里。
单元测试 vs 集成测试:分清楚再动手
很多人分不清这两个概念,我建议用一张表格来看区别:
| 维度 | 单元测试 | 集成测试 |
|---|---|---|
| 目标 | 验证单个类/方法的行为 | 验证多个模块之间的协作 |
| 依赖 | 尽量无依赖,或使用 Mock 替代 | 可依赖真实组件(数据库、网络等) |
| 运行速度 | 毫秒级,极快 | 秒级或更慢 |
| 稳定性 | 高,不受外部环境影响 | 低,网络和服务状态会影响结果 |
| 使用场景 | Repository、ViewModel 等业务逻辑 | API 真实调用、数据库读写等 |
你想想看,如果每个测试都去调真实接口,跑一轮几百个用例得多久?我见过团队用集成测试当单元测试用,结果 CI 管道动不动就超时,开发人员怨声载道。
我曾经在一个项目中把所有测试都写成集成测试,后来重构时改个 ViewModel 都得修十几个测试。教训就是:单元测试要轻量,Mock 要到位,别把耦合带到测试里。
Mock 适配器在这中间扮演什么角色?
Retrofit 官方提供了 Mock 适配器,它的核心能力很简单——拦截网络请求,直接返回预设的响应,不走真实 HTTP 调用。说白了,就是让你在没有后端的情况下,也能把前端的网络层测透。
我个人习惯用 Mock 适配器来做两件事:
- 单测中的快速 Mock:给每个 API 定义好正常返回、异常返回、空返回等场景,测试 ViewModel 或 Repository 能否正确处理。
- 集成测试中的依赖替换:比如你想测试整个登录流程,但不想真往认证服务器发请求,就可以用 Mock 适配器模拟一个假的 返回。
为什么不用别的 Mock 库呢?因为 Retrofit 的 Mock 适配器是原生支持的,配置文件少,使用简单,还和我们常用的 OkHttp、Gson 无缝衔接。你看下面这个代码:
val mockRetrofit = Retrofit.Builder()
.baseUrl("http://localhost/")
.addConverterFactory(GsonConverterFactory.create())
.client(OkHttpClient.Builder()
.addInterceptor(MockInterceptor()) // 自定义拦截器做 Mock
.build())
.build()
但这里有个问题,用拦截器做 Mock 虽然灵活,但需要自己写匹配逻辑。Retrofit 官方的 Mock 适配器更优雅——它直接继承了 CallAdapter.Factory,你只需指定一个 BehaviorDelegate,就能控制每次请求的返回。
单元测试保证「代码逻辑正确」,集成测试保证「系统协作正常」。Mock 适配器让单元测试真正脱离网络依赖,跑得又快又稳。
本章知识体系总览
下面的 SVG 图帮你理清 Mock 适配器在整个测试流程中的位置和作用。
图中清晰展示:测试痛点 → Mock 适配器(解决方案)→ 单元测试/集成测试的分类应用。有了 Mock 适配器,你可以在开发阶段就写好完备的测试用例,后端接口变了也不用慌,改改 Mock 数据就行。
什么时候该用,什么时候不该用?
我再说一个实用建议。Mock 适配器不是万能的,它适合以下场景:
- 单元测试 Repository 和 ViewModel—— 用 Mock 模拟成功/失败/异常三种状态,覆盖率拉升很快。
- UI 测试中的网络层替换 —— 你写 Espresso 测试时,不希望每次请求都等真实的服务器响应吧?Mock 一下就行。
- 演示或调试 —— 会议演示时,网络不好翻车太尴尬。提前用 Mock 适配器写好假数据,稳定展示。
但下面这些情况,就不要用 Mock:
- 想验证真实服务器行为 —— 比如检查 API 的响应结构是否真的变化,那就必须用集成测试走真实请求。
- 性能压测 —— Mock 不经过网络,测不出实际瓶颈。
团队一般把单元测试覆盖率目标定在 80% 以上,其中网络层相关的全部用 Mock 适配器来做。集成测试只覆盖关键路径,数量控制在 10 个以内,这样 CI 跑一次全量测试不会超过 5 分钟。
本章小结
我们得明确一个认知:测试的本质是验证逻辑正确性,而不是验证服务是否在线。Mock 适配器帮我们切断了外部的干扰,让测试回归本源。下一阶段我们就开始动手搭建它,你准备好了吗?