上个季度接了个后台管理系统的活,前端三个人,后端接口只完成了一小半,产品那边又定了两周后看可点击演示。这种局面做过交付的人都清楚,卡点往往不在技术难度,而在节奏对不上:前端等着接口写页面,后端被催着加班,测试环境里的数据还三天两头被人改坏。为了把前端从"等接口"的循环里解放出来,我把几款本地接口模拟工具挨个试了一遍,最后把主力工具定成了 Mockoon。它是一款完全跑在本地的开源接口模拟(API Mocking)桌面工具,不需要注册账号、不依赖任何远程平台,装完就能建环境、写路由、造数据,几秒钟给出一个能被浏览器和移动端真正请求到的假接口。这篇内容就是我这段时间用下来的完整记录:从装到用,从单条路由到整套环境管理,包括踩过的坑和几套可以直接抄走的配置模板,适合正在做前后端分离、需要自测和构造异常场景的开发者,也适合给演示版本准备假数据的同学。
1. 先想清楚 Mockoon 到底替你解决什么问题
1.1 一个真实的前后端联调现场
去年那套系统里有个"订单列表"页面,前端需要拿到分页数据、状态筛选、空列表、超时、500 报错这五种情况下的表现。如果按传统流程走,前端得等后端把接口写完、部署到测试环境,然后再去找人手动改数据造异常。更麻烦的是,后端为了让我看到"超时",得在代码里临时加一段 sleep;为了让我看到 500,还得硬塞一个抛异常的开关。等联调完,这些临时改动还得记得删掉,忘了删就是生产事故的种子。
Mockoon 改变的是这个流程的起点。后端只要把接口文档给出来,哪怕只是一段 Word 里的 URL 和字段说明,我这边就能在本地把接口"演"出来:状态码、响应头、响应体、延迟、甚至随请求参数变化的分支逻辑,全都由我自己控制。前端什么时候需要异常场景,我改一条规则就行,不用求人,也不用污染任何人的代码库。
这件事的价值不只是"快"。它把接口的不确定性从外部依赖变成了内部变量——前端页面能不能扛住后端抖动,这个问题的答案不再取决于后端今天有没有空,而取决于我有没有把异常响应配出来。
1.2 Mockoon 的产品形态与定位
第一次打开 Mockoon 的时候我有点意外,因为它长得太朴素了:一个左侧列表、一个中间编辑区、一个底部日志面板,没有花哨的图表,没有引导弹窗,甚至连登录入口都没有。这种朴素恰恰是它的定位——它不是一个"接口协作平台",而是一个纯本地的开发工具,性质更接近 Postman 或 JSON Server,而不是那些需要团队账号的在线 Mock 服务。
它的核心模型只有四层,理解这四层就理解了全部:
- 环境(Environment):一套完整的 Mock 服务配置,对应一个监听端口。一个项目可以建多个环境,比如"日常测试"和"演示专用"。
- 路由(Route):一条接口,由 HTTP 方法加路径组成,比如
GET /api/users/:id。 - 响应(Response):一条路由可以有多个响应,每个响应有自己的状态码、响应头、响应体和触发规则。
- 数据桶(Data Bucket):环境级别的一份 JSON 数据,可以被多条路由共享和引用。
这套模型的设计意图很明显:真实接口的复杂度主要体现在"同一个 URL 在不同条件下返回不同结果",所以它把"响应"从"路由"里拆出来单独管理。这个设计在后面配置业务场景时会省下大量重复劳动,我在第 4 节会详细展开。
另外值得提前说明的是,Mockoon 的桌面端是免费开源的,跨 Windows、macOS、Linux 三个平台,底层用的是 Electron。项目本身还提供了命令行版本和容器镜像,用来把配置好的环境跑在服务器或流水线里,这部分我在第 5 节讲。
1.3 同类方案横向对比与选型逻辑
选型这件事我从来不看谁功能最多,而是看"哪种方案在团队里活得更久"。功能再全,如果每次改配置都要连内网、要审批、要等同步,三周之后就没人用了。我把当时试过的几种方案列了个表,对比维度是我自己真正在意的几项:
| 方案 | 是否需要网络/账号 | 运行位置 | 动态数据能力 | 团队共享成本 | 适合场景 |
|---|---|---|---|---|---|
| Mockoon | 不需要 | 本地桌面或容器 | 模板函数 + 随机数据,很强 | 配置文件可进 Git | 个人开发、演示、异常场景构造 |
| 在线 Mock 平台 | 需要 | 云端 | 中等 | 低,但依赖第三方可用性 | 跨团队协作、对外演示 |
| JSON Server | 不需要 | 本地进程 | 弱,基本是静态增删改查 | 需要自己写启动脚本 | 快速起一套 CRUD 假数据 |
| 自写 Express/Fastify | 不需要 | 本地进程 | 完全自由 | 要写代码、要维护 | 逻辑极其复杂的模拟场景 |
| 抓包工具录制回放 | 不需要 | 本地 | 弱,数据是死的历史快照 | 导出文件较大 | 复现线上问题、排查历史请求 |
我最后选 Mockoon 的理由有三条。第一条是零依赖启动,不用先起一个 Node 服务,也不用写任何代码,配置界面点几下就能跑,这对非后端同学特别友好——我们组的产品经理后来自己都会改返回文案了。第二条是配置即文件,一个环境可以导出成一份 JSON,扔进 Git 就能做版本管理和评审,这比"某人电脑上有一份配置"靠谱得多。第三条是模板能力够用,随机姓名、UUID、时间戳、循环生成数组这些都内置了,造出来的数据看起来像真的,前端在联调时更容易发现布局问题,比如名字特别长会不会把表格撑破。
自写 Express 的方案我也试过,灵活度确实最高,但问题在于它变成了一个新项目:要有人维护依赖、要处理跨域、要写文档告诉别人怎么改。当一个"辅助工具"开始需要维护的时候,它的性价比就崩了。
2. 装好到跑通第一个接口,十分钟够用
2.1 下载安装与环境准备
安装这一步没什么可讲的,官网下载对应平台的安装包,双击装完就行,Windows 上会生成一个可执行程序,macOS 上是 dmg 拖进应用目录。整个过程不需要额外的运行时,不需要装 Node,也不需要配置任何环境变量。这一点对刚接触的同学很重要,很多人被 JSON Server 卡住的原因就是 Node 版本不对或者 npm 源的问题,而 Mockoon 把运行时打包进去了。
安装完之后我建议做两件事。第一件是把默认端口记下来,默认是3000,如果你本机已经跑了前端开发服务器或者别的服务,很可能撞车,早点改掉省得后面排查半天。第二件是找到"环境数据"的存盘位置,Mockoon 会自动保存你的编辑内容到本机应用数据目录,但这个位置不方便团队共享,所以养成立即导出的习惯:导出成一份 JSON 文件,放到项目的mock/目录下,跟着代码一起提交。这样别人 clone 下来导入一下就能用,换电脑也不慌。
如果你的机器上有比较严格的安全软件,第一次启动 Mockoon 的时候可能会弹窗询问是否允许它监听本地端口,选择允许即可。这类监听行为是本地开发工具的常规操作,服务本身只在本机回环地址上暴露,不涉及任何对外数据发送。
2.2 界面四大区域速览
Mockoon 的界面拆得很清楚,我按使用频率从高到低说:
左侧是环境列表和路由列表,上下分成两块。上半部分是环境,每个环境前面有个开关,控制这个 Mock 服务是否在监听。下半部分是当前环境下的所有路由,路由列表的排序是有意义的,这个后面讲规则的时候会重点说。
中间是编辑区,选中的是环境就显示环境配置(端口、主机名、默认响应头、CORS 开关、TLS 设置等),选中的是路由就显示这条路由的路径、方法、以及下面的多个响应配置。响应配置区域又能切到"请求体匹配""响应头""响应体"这几个标签页,日常改得最多的就是响应体。
底部是日志面板(Logs),记录每一个到达到你这个 Mock 服务的请求,包含时间、方法、路径、命中的状态码、请求头、请求体。这个面板是我用得最勤的功能,前端说"接口返回不对"的时候,我先看日志里到底有没有请求进来、请求参数长什么样,能省掉一大半互相甩锅的时间。日志面板里还有个开关控制是否记录,如果压测场景下请求太多,可以临时关掉减少干扰。
右上角是启动/停止按钮,以及环境切换的下拉框。这里有个小细节:每条路由前面也有一个独立的开关,可以单独把某条路由停掉,用来验证前端在接口不存在时的表现。这个功能我在测试"接口下线"这类场景时用得挺多。
2.3 手把手创建第一个可访问的接口
我按完整流程走一遍,你可以跟着操作:
第一步,新建一个环境,起个能看懂的名字,比如demo-user-api。端口填3001,主机名先保持默认的127.0.0.1或者localhost。主机名这个字段很关键,默认只监听本机,只有把它改成0.0.0.0才能让同一局域网的同事访问到,这点我在 2.4 会展开。
第二步,在这个环境里新建一条路由。方法选GET,路径填/api/users。注意路径不要带域名,也不要带查询字符串,查询参数是单独处理的。如果你习惯写/api/users?page=1,那样会匹配不上,因为 Mockoon 是按路径结构匹配的。
第三步,配置响应。状态码保持200,响应体类型选内联(Inline),然后粘贴一段 JSON:
{ "code": 0, "message": "ok", "data": { "total": 3, "list": [ { "id": 1, "name": "张三", "role": "admin" }, { "id": 2, "name": "李四", "role": "editor" }, { "id": 3, "name": "王五", "role": "viewer" } ] } }第四步,确认这条路由和它下面的响应都处于开启状态,然后点左上角的启动按钮。启动成功后环境名旁边的指示灯会变绿,底部日志面板会开始记录。
第五步,打开浏览器访问http://localhost:3001/api/users,你应该能看到刚才那段 JSON。如果用的是前端项目,把接口基地址临时指到http://localhost:3001就行,不需要改任何业务代码——这也是我喜欢它的原因之一,对接方式跟真实后端完全一致。
注意:新建路由后很多时候返回 404,八成是路由或响应没启用。Mockoon 的路由和响应都有独立的开关,新建时默认是开的,但如果你从别人那里导入配置,导入后要把整个环境和下面的开关都检查一遍。
2.4 端口、主机名与局域网共享的几个坑
这一节说的全是血泪。端口冲突是最常见的,症状是点启动按钮后服务起不来或者日志里没有任何记录。排查方式很简单,把端口换成3002、3003试,或者用系统命令看一下端口占用情况。Windows 上可以用netstat -ano | findstr 3000,macOS 和 Linux 上用lsof -i :3000。
主机名字段经常被忽略。默认的127.0.0.1意味着只有你自己这台机器能访问,手机真机调试、同事联调、容器内访问都会失败。改之前要想清楚一件事:一旦改成0.0.0.0,同一个局域网内的其他人就都能访问你的机器,所以演示完记得改回来。如果只是想给同事临时看,用0.0.0.0加对方的 IP 访问是够用的;如果是长期共享,我更建议用第 5 节的命令行方式跑在一台测试机上。
TLS 场景也要提前考虑。有些前端项目的请求库或者浏览器安全策略,在 https 页面里不允许请求 http 接口。Mockoon 的环境设置里可以开启 TLS 并指定证书文件,用于这类必须走 https 的场景。自签证书在浏览器里会报警告,测试环境点继续访问就行,别在这上面纠结太久。
还有一个细节:环境级别的默认响应头。如果你希望所有接口都带上某个自定义头,比如X-Mock-Source: demo,在环境设置里配一次就够了,不用每条路由重复加。这在你想确认"前端到底请求的是 Mock 还是真实后端"的时候很好用,一眼就能分辨。
3. 把假数据做得像真的:响应配置与模板引擎
3.1 状态码、响应头、延迟的实操姿势
响应配置里最容易被低估的是延迟(Latency)。很多前端 bug 只在网络慢的时候才暴露,比如加载态一闪而过、竞态导致旧请求覆盖新请求、骨架屏高度抖动。Mockoon 允许给响应配置固定延迟或者一个随机区间,我通常给列表接口配300到800毫秒的随机延迟,给提交类接口配800到1500毫秒。别小看这个设置,它比任何代码评审都更容易发现问题。
随机延迟的用法很简单,在延迟字段里填一个区间,比如300-800,单位是毫秒。这个设计比固定值更贴近真实现场,因为真实网络从来不会每次都一样快。
状态码方面,我习惯把异常响应单独做成一条路由下的另一个响应,而不是去改正常响应的状态码。原因在第 4 节的规则部分会讲清楚:一条路由多个响应,配合规则自动分流,比手动改来改去靠谱得多。
响应头里有两个高频操作。一是Content-Type,返回 JSON 时确保它是application/json,如果是 JSONP 或者 XML 记得同步改掉,否则前端解析会报错。二是跨域相关的那几个头,Mockoon 的环境设置里有一个 CORS 开关,打开后会统一补上跨域响应头,这是最省事的做法。如果你不想全局开,也可以在某条路由的响应头里单独加。
3.2 路由匹配:路径参数、通配与正则
路径写法决定了你能模拟多复杂的接口。基础写法就是静态路径,/api/users这种。进阶有两个方向:
路径参数用冒号声明,比如/api/users/:id。请求/api/users/42会命中,42可以在响应体里通过模板取出来用。这一点非常关键,因为详情类接口的响应必须和请求的 ID 对应上,否则前端点进详情页看到的是别人的数据,会以为自己写错了逻辑。
通配和正则用于处理模糊路径。比如你想让/api/files/2024/03/report.pdf和/api/files/2025/11/data.xlsx都命中同一条路由,可以用通配符写法*或者正则写法。正则写法的好处是能精确约束,坏处是可读性差,团队里其他人看不懂。我的建议是能用通配就用通配,正则只在真的需要约束格式时才上,并且一定要在路由名字里写清楚这条路由是干什么的,别让人对着^/api/v(\d+)/.*$发呆。
还有一个容易被忽略的点:大小写和结尾斜杠。/api/users和/api/users/在很多框架里是两个不同的路径,Mockoon 也会按字面匹配。前端团队里如果对这个没统一约定,就会出现"我这边能通别人那边 404"的情况。我现在的做法是在环境里同时配两条路由,一条带斜杠一条不带,成本极低,省事极多。
3.3 模板语法:把请求数据用起来
Mockoon 的响应体里可以写模板,语法是双大括号,能同时拿到请求数据和生成随机数据。这是它跟"纯静态 JSON 文件"拉开差距的地方。我常用的是这几类:
取请求里的值:
{ "userId": "{{urlParam 'id'}}", "page": {{queryParam 'page' 1}}, "keyword": "{{queryParam 'keyword'}}", "token": "{{header 'Authorization'}}", "nickname": "{{body 'user.name'}}" }urlParam取的是路径参数,queryParam取的是查询参数,header取请求头,body取请求体里的字段。注意queryParam后面那个第二个参数是默认值,请求里没带这个参数时会用默认值兜底,这个细节能避免前端忘记传参时你的 Mock 返回一堆空字符串。
生成随机数据用的是内置的随机数据生成器,配合模板调用,格式大致是这样:
{ "id": "{{faker 'string.uuid'}}", "name": "{{faker 'person.fullName'}}", "email": "{{faker 'internet.email'}}", "avatar": "{{faker 'image.avatar'}}", "city": "{{faker 'location.city'}}", "createdAt": "{{now 'YYYY-MM-DD HH:mm:ss'}}" }注意:随机数据的函数名在不同大版本之间改过。早期版本用的是比较老的命名方式,新版本换成了带命名空间的新写法。如果你从别人那里导入了一份老配置,发现返回体里原样输出了
{{faker ...}}字样,大概率就是版本命名差异导致的,去官方文档查一下当前的函数名列表换掉即可。
这里有个使用心得:随机数据和固定数据要混着用。比如列表接口里如果每条记录的名字都是随机的,前端排查问题时对不上号;但如果全是张三李四,又测不出长文本溢出的问题。我的做法是关键字段固定(比如第一条永远是"张三",方便截图和写测试用例),其余记录用随机值,兼顾两边。
3.4 动态数组:一次生成二十条列表数据
列表页的测试需求很具体:要能快速切"3 条数据""20 条数据""空列表"。空列表最简单,把list写成空数组就行。20 条数据如果用静态 JSON 手写,改一次要人命。Mockoon 提供了循环语法,可以按次数复制内容:
{ "code": 0, "total": 57, "page": {{queryParam 'page' 1}}, "list": [ {{#repeat 20}} { "id": {{@index}}, "name": "{{faker 'person.fullName'}}", "role": "{{oneOf (array 'admin' 'editor' 'viewer')}}", "score": {{faker 'number.int' 0 100}}, "createdAt": "{{now 'YYYY-MM-DD'}}" } {{/repeat}} ] }写这段的时候有两个细节要留意。一是循环体内的逗号处理,不同版本对末尾逗号的处理方式可能有差异,我的习惯是配好之后先在浏览器里请求一次,把返回的 JSON 粘到格式化工具里确认能解析通过,能解析就说明逗号没问题,别等前端报语法错误才回头查。二是@index从 0 开始,如果你的业务 ID 要求从 1 开始,直接写成表达式加一,或者在数据桶里维护一份真实 ID 列表。
这段配置解决的实际问题很具体:产品说"这个表格最多显示 19 行就要分页,你看看超过会不会有问题"。原来我得手动复制粘贴二十遍,现在改个数字,刷新,两秒钟搞定。
3.5 数据桶:让多条路由共享同一份数据
数据桶是我后来才用起来的功能,用上之后配置文件干净了一大截。它的思路是:把一份 JSON 数据存在环境级别,多条路由通过引用去读它。
举我实际遇到的例子。用户列表、用户详情、用户搜索这三个接口,原来的做法是各写各的数据,结果张三在列表里 ID 是 1,在详情页里 ID 变成了 7,前端调试的时候直接懵了。改成数据桶之后,数据只维护一份,列表接口做切片,详情接口按 ID 去查,搜索接口按关键字过滤,三者天然一致。
数据桶的数据在环境级别定义,响应体里通过引用的方式取出来,配合循环和条件判断就能实现很接近真实后端的行为。较新的版本里,Mockoon 还支持基于数据桶直接生成一套增删改查路由,对于只有简单 CRUD 需求的场景,几分钟就能起一套能跑通的假后端。
这里有个经验:数据桶不适合放太大的数据。它本质是内存里的一份 JSON,几百条记录没问题,几万条就会让你的编辑界面开始卡,而且配置文件体积会膨胀到没法做代码评审。大数据量的场景我建议还是用脚本生成后写进一个 JSON 文件,然后用响应体的"文件"模式去返回,编辑界面保持轻快。
4. 规则与场景编排:让同一个接口演出多种结果
4.1 响应规则的三要素与匹配顺序
一条路由可以挂多个响应,每个响应可以带一组规则。规则由三部分组成:目标(看哪里)、修饰符(怎么比)、值(比什么)。三部分都满足,这个响应才算命中。
目标是可选项里最丰富的一块,常用的有:请求体字段、查询参数、请求头、Cookie、路径参数、请求序号。我的经验是,最常用来做业务分流的其实是请求体字段和查询参数。比如登录接口靠请求体里的用户名分流,列表接口靠查询参数里的筛选条件分流。
修饰符决定比较方式,等于、正则、为空、不为空、包含这些覆盖了绝大多数需求。这里有个坑:不要用正则去比对一个本来就该用等于判断的字段,写起来复杂,还容易因为大小写或空格匹配不上,排查起来比写规则还费时间。
匹配顺序是按响应列表从上往下,第一个全部规则命中的响应胜出。没有配规则的响应通常作为兜底放在最下面。所以配规则时有一条铁律:规则越具体的响应放得越靠上,越宽泛的放得越靠下。我见过有人把兜底响应放在第一条,结果下面所有带规则的响应全部失效,查了半天以为是规则写错了,其实只是顺序问题。
4.2 一个登录接口的三种剧本
我拿登录接口举个完整例子,这是最能体现多响应价值的场景。同一条路由POST /api/login,我配了三个响应:
第一个响应,规则是请求体里的username等于测试账号、password等于正确密码,返回 200,响应体里给 token 和用户信息。这是正常流程。
第二个响应,规则是请求体里的password不等于预期值,返回 200 但业务码是错误码,响应体里给"用户名或密码错误"的提示。为什么用业务错误码而不是 401?因为真实项目里很多后端就是这么设计的,前端必须练会处理这种"HTTP 成功但业务失败"的情况。
第三个响应,不带任何规则,放在最下面兜底,返回 400 和一段参数校验失败的提示。这样前端传了空值、传了非法格式,都能看到一个合理的错误,而不是 404。
这套配置带来的直接后果是:前端的错误提示弹窗、表单校验、登录态失效处理,全都能在本地完整走一遍。以前这些逻辑要等后端把三种情况都实现出来才能测,现在我在工位上五分钟就配好了。
同样的套路可以用在支付、下单、文件上传这些接口上。我给自己定的配置规范是:每个核心接口至少三个响应——正常、业务失败、系统异常。系统异常那个响应配 500 加一段错误堆栈样式的 JSON,用来验证前端的兜底页面。
4.3 转发模式与回调:联调切换的正确姿势
写 Mock 的人都会遇到一个尴尬时刻:后端说接口好了,你把前端地址从 Mock 切到真实后端,发现字段名跟文档不一致,一堆地方要改。更难受的是切回去又要重新改一遍地址。
Mockoon 的转发模式(Proxy 模式)能缓解这个问题。开启之后,环境收到的请求会被转发到指定的真实后端地址,你可以在中间观察请求和响应。这个能力在两种场景下特别有价值:一是后端已经提供了一部分接口,你想边用真实数据边 Mock 未完成的接口;二是排查"到底是我前端传错了还是后端返回错了",把请求转过去对照日志,一目了然。
需要提醒的是,转发模式开启后要注意响应内容别被意外缓存或者篡改,用它排查问题时保持配置简单,用完及时关掉。另外要留意真实接口的返回结构可能跟你 Mock 的不一样,切换前先把字段对一遍,能省下不少返工。
另一个进阶功能是回调:某个响应返回之后,触发对另一个地址的请求。这个能力可以模拟"提交订单后异步通知"这类链路,但配置复杂度会上升,我一般只在需要演示完整链路的时候才用,日常开发很少碰。
4.4 用多环境管住不同配置
我现在的习惯是一个项目建三个环境:dev-local、demo、e2e-test。三个环境的路由基本一样,区别在于端口、延迟和数据。
dev-local用于日常开发,延迟给中等,数据里包含各种边界情况(超长文本、空值、特殊字符)。demo用于给客户演示,端口换一个,延迟调低到 100 毫秒以内,数据只保留好看的那几条,避免演示时出现"测试用户 001"这种尴尬内容。e2e-test用于自动化测试,延迟设为 0,数据完全固定,保证每次跑的结果一致——随机数据在这里是灾难,会让断言随机失败。
环境之间可以整体复制,不用一条条重建。复制完之后改端口、改数据,几分钟的事。这个习惯养成之后,最大的好处是演示当天我不用临时改配置,直接切环境启动就行,减少了现场手忙脚乱的概率。
5. 命令行与团队协作:把 Mock 服务变成团队资产
5.1 环境文件的导入导出与版本管理
桌面端配好的环境可以导出成一份 JSON 文件,格式是可读的,包含所有环境、路由、响应、规则和数据桶。这份文件是团队协作的核心载体。
我的做法是在项目根目录建一个mock/目录,把导出的文件放进去,命名带上用途,比如user-api.mock.json。提交到版本库之后,新同事拉下来导入一下就能用。有几个实践细节值得说:
一是导出频率。我一般完成一批配置就导出一次,因为桌面端的数据存在本机应用目录里,重装系统或者换电脑就没了,导出到项目里才是真的存下来。
二是评审粒度。配置文件是 JSON,改动会体现在 diff 里,接口路径、状态码、响应体都能被评审到。如果一次提交里 diff 有上千行,说明改动太大,应该拆开。另外提醒一句,导出的文件里如果包含随机数据模板,diff 会比较容易看,但如果包含大量静态数据,diff 会很长,这种时候可以考虑把大块数据拆到单独维护的文件里。
三是敏感内容。Mock 数据里千万别放真实的用户信息、真实的密钥或者内部系统地址。这不是洁癖,是真实发生过的教训:有人把生产环境的测试账号写进了 Mock 配置,一起提交进了公开仓库。用假名字、假邮箱、假手机号,成本为零,风险也为零。
5.2 命令行启动与容器化
桌面端适合个人开发,但有两类场景它顶不住:一是需要长期给团队提供一个共享的 Mock 服务,二是希望把 Mock 服务塞进自动化流程。这时候用命令行版本。
安装和启动的流程大致是这样:
npm install -g @mockoon/cli mockoon-cli start \ --data ./mock/user-api.mock.json \ --port 3001 \ --hostname 0.0.0.0--data指定配置文件的路径,--port指定监听端口,--hostname设成0.0.0.0才能被同网段的其他机器访问。如果你的配置文件里包含了多个环境,可以用索引参数指定跑第几个,注意索引从 0 开始,跑错环境是新手最常见的错误,症状是接口返回的数据跟你预期完全不是一回事。
容器方式在持续集成里更常见,大致长这样:
docker run -d --name mock-api \ -p 3001:3001 \ -v $(pwd)/mock:/data \ mockoon/cli:latest \ --data /data/user-api.mock.json \ --port 3001 --hostname 0.0.0.0这套用法的价值在于:Mock 服务变成了一个可以随时拉起的标准组件,谁都不需要在自己电脑上折腾环境。我们的自动化测试流水线里就跑了一个容器,测试用例启动前先把它拉起来,跑完销毁,全程无人干预。
注意:容器里如果配置文件路径写错,进程通常会直接退出,日志里会有明确提示。排查时先看容器日志,别急着怀疑镜像问题。另外挂载目录时尽量用绝对路径,相对路径在不同终端下的解析结果可能不一致。
5.3 接入前端本地开发和自动化测试
接入前端项目有两处需要改。开发环境里通常有一个接口地址的配置项,把它指向 Mock 服务的地址就行,比如http://localhost:3001。很多脚手架支持通过环境变量覆盖,用起来更方便,改完不用提交代码,本地生效即可。
自动化测试里接 Mock 服务的思路略有不同,重点是数据要可预测。我会为测试单独准备一个环境,所有响应都是固定值,延迟为 0,不启用任何随机数据。断言里写的期望值能稳定对上,测试才不会变成随机失败的噪音源。如果测试需要造不同的响应,就在路由上多配几个响应,用请求参数区分,而不是在测试代码里改 Mock 配置。
还有一个实际用起来很舒服的场景:离线开发。坐飞机或者网络环境差的场合,真实接口请求会超时,整个开发节奏被打断。把接口指向本地 Mock 服务,读写都是本机的,手感和在线时没有区别。
5.4 从接口文档反向生成路由
接口文档写完再手动一条条配路由,是个挺枯燥的活。较新版本的 Mockoon 支持导入接口描述文件,把路径、方法、字段结构批量生成成路由,省掉大量重复输入。
我实际用下来的体会是,生成出来的东西适合当骨架,不适合直接当成品。文档里写的字段类型和示例值通常是抽象的,生成出来的响应体里可能只有字段名没有像样的数据。我的流程是:先导入生成骨架,然后花十几分钟给核心接口补上随机数据模板和规则,剩下的边缘接口就保持骨架状态,反正日常也不怎么用。
同样地,Mockoon 也能把配置导出成标准的接口描述文件,用于同步给其他工具或者交给后端核对。这个能力在接口契约需要对齐的项目里很有用,能避免"我 Mock 的字段名和文档不一致"这类低级问题。
6. 常见问题排查速查表与踩坑实录
6.1 请求打不通,按这个顺序查
我把排查顺序固定下来之后,解决这类问题的平均时间从十几分钟压到了一两分钟:
| 现象 | 最可能的原因 | 处理方式 |
|---|---|---|
| 浏览器连不上,提示拒绝连接 | 服务没启动、端口被占用、环境开关没打开 | 看左上角指示灯,换端口重试,确认环境开关 |
| 浏览器能开,业务代码报跨域 | 没有输出跨域响应头 | 环境设置里打开跨域开关,或单独加响应头 |
| 返回 404 | 路径不匹配,方法不对,结尾斜杠差异 | 对照日志里的实际请求路径,补一条对应路由 |
| 返回的内容是模板原文 | 响应体里没有开启模板处理,或者函数名版本不对 | 检查响应的模板开关,核对随机数据函数名 |
| 拿到的参数是空字符串 | 取值函数用错了,或者参数名拼错了 | 路径参数用路径取值,查询参数用查询取值 |
| 规则不生效,永远命中同一条 | 响应顺序问题,兜底响应排在了前面 | 把具体规则往上移,兜底放最后 |
| 同事访问不到 | 主机名还是回环地址,或者系统防火墙拦截 | 改成允许外部访问的地址,放行端口 |
排查的核心思路只有一句话:先确认请求有没有到达,再看它命中了哪条响应。日志面板里两样都能看到,所以遇到问题第一件事永远是看日志,而不是改配置。
6.2 几个我踩过的坑
第一个坑是在循环里写了多余的逗号。当时配一个列表接口,本地能返回,前端一解析就报 JSON 语法错误。折腾了一会儿才发现是循环展开后多了一个逗号。后来我养成了习惯:任何带循环或者条件判断的响应体,配置完第一件事是把返回结果复制到格式化工具里验证一次,通过之后再通知前端。
第二个坑是把随机数据和固定断言混在了一起。刚开始跑自动化测试的时候,我复用了开发环境的配置,里面有随机生成的名字和 ID,结果测试时不时就红一次,每次原因还都不一样。后来拆出专门给测试用的环境,全部改固定值,测试才真正有意义。这件事让我记住一个原则:随机数据是给人看的,固定数据是给机器校验的,两者不要混。
第三个坑是规则写得太宽泛。某次我在列表接口上配了一条规则,只判断查询参数里的状态字段非空,结果前端传了任何筛选条件都会命中这条,后面正常数据的响应永远轮不上。解决方式是给每条规则加上具体值,而不是只判断"有没有值"。规则越精确,排查成本越低。
第四个坑是配置文件里的路径依赖。我在响应体里用了文件模式,指向一个本地绝对路径,自己电脑上跑得好好的,同事拉下来全是 404。后来改成相对项目根目录的路径,问题消失。凡是涉及文件路径的配置,都要假设别人是在另一台机器上用,绝对路径不用考虑。
6.3 关于中文和编码的两个细节
中文乱码这事我遇到过两次。一次是响应头里的Content-Type没带字符集声明,某些客户端会按默认编码解析,导致中文显示成问号。解决办法是在响应头里明确写上字符集。另一次是用文件模式返回一个带中文的 JSON 文件,文件本身的保存编码不是通用的那种,改成常见编码后正常。
所以我的建议是:中文内容的接口,响应头一定写全;用文件模式返回数据时,文件编码统一成通用格式;如果前端用的是比较老的请求库,优先用内联方式写响应体,少走文件这条路。
6.4 一套可以直接抄的配置节奏
用了大半年,我现在的配置节奏基本固化了,写出来给你参考:
开工一个新模块,先花十分钟把核心接口的路径和方法建出来,响应体随便给个空对象,让前端能先把请求打通。等前端开始填页面,我再补数据结构,用随机数据模板把字段填满,加上中等延迟,让加载态和分页能被真实感受到。前端说某个交互要测异常,我就在对应路由下加一个带规则的响应,返回错误码或者 500。临近演示,切到演示环境,把数据换成好看的那一版,延迟调低。
整个过程里我基本不写代码,全是在界面里点。这也是我最后没有选自写服务的原因——它能让我把注意力放在业务场景上,而不是放在工具本身的维护上。有几次我甚至是在跟产品开会对需求的时候,现场把接口配出来给对方看,确认字段命名和交互逻辑,比画原型快得多。
最后再分享一个小习惯:我会在项目 README 里写一段三行的说明,告诉团队怎么导入这份 Mock 配置、怎么启动、端口是多少。这三行字省掉的沟通成本,比我写过的任何文档都高。工具本身从来不是难点,让团队所有人都知道它在哪里、怎么用,才是真正决定它能不能活下来的东西。