Mock技术概述
什么是Mock?先从我踩过的坑说起
记得我刚做性能测试那会,接了个支付系统的压测任务。联调环境里,银行接口隔三差五超时,一天只能跑两轮。后来才发现,根本不是系统不行,是上游在拖后腿。那时候我就想——要是能有个假接口替银行干活就好了。
嗯,这就是Mock干的事。说白了,Mock就是造一个替身对象,替代真实依赖。它能让你在测试时,不用真的调数据库、调第三方API、调外部服务。你预先告诉它:「下次有人问余额,就返回1000。」它就能乖乖照做。
我日常最常用的是两种Mock方式:
- 桩代码(Stub):直接返回固定数据,不关心调了几次。
- 模拟对象(Mock):除了返回数据,还会验证「有没有被调」「调了几次」。
你想想看,性能测试里我们绝大多数场景用的就是「桩」——我们只在乎返回快不快,不关心它内部怎么验。这一点后面还会展开。
Mock的核心价值——为什么要用替身?
我把它总结成五个关键词,每个都是我亲测有效的血泪经验。
| 价值 | 说明 | 我遇到的真实案例 |
|---|---|---|
| 解耦 | 测试代码不依赖外部环境,一跑就灵 | 有一次第三方接口换了SSL证书,整个压测环境挂了3天,换成Mock后永远不受影响 |
| 提速 | Mock返回延迟可以压到毫秒级 | 原来测一个流程要等数据库读写+外部调用,平均200ms;Mock后降到1ms,压测QPS直接翻倍 |
| 可控 | 指定返回码、超时、异常,随心所欲 | 我在测试降级逻辑时,故意让Mock返回500,瞬间验证了熔断效果 |
| 成本 | 减少环境搭建、维护、License费用 | 以前为了压测要申请两个付费沙箱,一个月花好几万。Mock实现后,一台虚拟机搞定 |
| 隔离 | 问题定位不甩锅,到底是谁的锅一眼看出 | 某次压测响应变慢,Mock去掉后再跑,发现是中间件线程池满了——没有Mock我还在跟对方扯皮呢 |
useRealService=true/false。本地开发跑Mock,集成环境跑真实,两边都能验证,不出乱子。
Mock在性能测试中的地位——它到底有多重要?
很多人觉得Mock只是开发做单元测试用的东西。说实话,我以前也这么以为。直到我被「真环境压不动」这件事反复摩擦,才意识到Mock在性能测试里其实是个关键角色。
1. 原理验证阶段:先跑通再说
压测脚本写完后,你是不是也想先试一下能不能跑?但如果依赖的服务没就绪,脚本根本跑不起来。这时候Mock的价值就出来了——用一个假接口快速验证脚本逻辑,比如参数拼对了没、断言写对了没。我每次写新脚本,都会先挂Mock跑一遍,确定没问题了再切到真实环境。
2. 构建可控的压测环境
真实环境里,依赖服务的状态你控制不了。数据库可能脏了,缓存可能过期,第三方可能限流。而你要测的是自家系统的极限,不是别人的极限。所以优秀的性能工程师会用Mock把外部依赖全部替换掉,只留下被测服务,这样压出来的数据才有说服力。
# 一个典型的Mock Server配置示例(简化版)
services:
- name: payment-gateway
mock:
url: /api/pay
method: POST
response:
status: 200
body: '{"code":"SUCCESS","transactionId":"mock_123"}'
delay: 5ms # 模拟网络延迟
scenario:
- trigger: after_10000_calls
then: return_timeout # 第10001次调用模拟超时
3. 异常场景模拟——生产里才不报异常呢
真实环境里想造个「超时」或「返回空值」?你得等。但Mock一秒搞定。我的习惯是写压力测试场景时,故意把Mock的返回改成各种极端情况:200ms超时、50%概率返回错误码、偶发乱序数据……这些在线上都可能发生,提前压测能帮你发现系统脆弱点。
4. 回放流量录播
这是一项进阶应用,也是本课程后面章节的重点。简单说就是录制生产环境的真实流量,然后用Mock把这些请求「回放」到压测环境里。和单纯的Mock不同,它保留了真实的请求分布和参数组合,更逼真。
5. 建立性能基准线
我在项目中经常遇到:每次发布前都要重新压一次,但环境参数总变。后来我发现只要把外部依赖全部Mock固定住,压出来的数据纵向比较就有意义了。性能是降了还是升了,一眼就能看出来。