常见 Mock 工具对比:Mountebank、WireMock、Hoverfly
做 CI 流水线 Mock 回放,选对工具是关键一步。我自己折腾过好几个项目,从早期的简单 stub 到后面复杂的协议模拟,踩过不少坑。今天把这几个主流工具拉出来聊聊,帮你快速选型。
选工具前先问三个问题
我在项目中每次引入新的 Mock 工具,都会先问自己:
- 我的服务依赖什么协议? 大部分场景只是 HTTP,但如果碰到 TCP 或 SMTP,选择面就窄了。
- 回放验证需要多精细? 是只检查返回码,还是要验证请求体里的具体字段?
- CI 环境能跑什么运行时? Java 要装 JDK,Node 要装 npm,Go 单文件直接跑。这个得想清楚。
Mountebank:协议最广,但配置偏重
Mountebank 有几个我很欣赏的特点:它原生支持 HTTP、HTTPS、TCP、SMTP,甚至还能模拟 IMAP。我记得有一次需要 Mock 一个遗留系统的 SMTP 行为,WireMock 和 Hoverfly 都搞不定,最后是 Mountebank 救的场。
我的习惯: 如果你的系统涉及多个协议,直接上 Mountebank,避免后面再换工具。不过它的谓词匹配语法有点啰嗦,建议提前写好模板。
举个简单的例子,模拟一个 TCP 回显服务:
# 启动 Mountebank
mb --configfile mbconfig.json
# 配置 TCP stub (通过 REST API)
curl -X POST http://localhost:2525/imposters \
-H 'Content-Type: application/json' \
-d '{
"protocol": "tcp",
"port": 4545,
"stubs": [{
"predicates": [{
"equals": { "data": "ping" }
}],
"responses": [{
"is": { "data": "pong" }
}]
}]
}'
避坑: 我曾经用 Mountebank 做大批量并发请求的 Mock,发现默认的 Node.js 单线程模型容易成为瓶颈。如果你有高吞吐需求,建议加上 clustering 或多实例分流。
WireMock:Java 生态之王,录制回放最成熟
WireMock 是我在 Java 微服务项目里用得最多的工具。它的录制功能真的太方便了——启动 WireMock 作为代理,跑一遍真实的集成测试,所有请求响应自动录成 mapping 文件。后续 CI 里直接重放,省时省力。
你想象一下这个场景:
- 开发环境启动 WireMock 在
localhost:8080 - 配置被测服务将外部调用指向
localhost:8080 - 跑一遍真实业务流程, WireMock 自动记录所有请求和响应
- 把 recordings 目录下的 mapping 文件提交到 Git
- CI 中启动 WireMock 并加载这些 mapping,测试完全不依赖真实下游
我个人特别喜欢它的 请求计数验证:
// Java 测试中验证某个接口被调用了 2 次
verify(2, postRequestedFor(urlEqualTo("/api/orders"))
.withHeader("Content-Type", containing("application/json")));
不过 WireMock 的短板也很明显——它只支持 HTTP/HTTPS,而且 Java 进程在 CI 里启动稍慢。要是你的 Pipeline 是用容器跑的,可以考虑把 WireMock 做成 sidecar 容器。
Hoverfly:轻量又快速,gRPC 有望
Hoverfly 是后来者,但它的设计理念很对我的胃口。一个 Go 编译的静态二进制文件,只要 10MB 左右,启动时间不到 100ms。在 CI 里可以直接 hoverfly -webserver 就跑起来了,没有任何运行时依赖。
我在一个 Serverless 项目里用过 Hoverfly 做 Mock。那个项目用 Node.js 写的,CI 环境很精简,连 JDK 都不想装。Hoverfly 完美适配。它还支持 diff 模式——回放时如果实际请求和录制的请求有差异,可以高亮显示不同点。
# 录制模式
hoverctl mode capture
curl http://localhost:8500/real-api/users/1
hoverctl export --destination simulations.json
# 回放模式
hoverctl mode simulate
curl http://localhost:8500/real-api/users/1 # 返回录制的响应
关键对比指标(基于我实际压测数据):
| 特性 | Mountebank | WireMock | Hoverfly |
|---|---|---|---|
| 协议支持 | HTTP/TCP/SMTP/HTTPS | HTTP/HTTPS | HTTP/HTTPS(gRPC实验) |
| 录制回放 | 需手动编写 stub | ✅ 原生录制 + 回放 | ✅ 原生录制 + 差异比对 |
| 运行时依赖 | Node.js | Java 8+ | 无(Go 单文件) |
| CI 启动耗时 | ~300ms | ~2s(JVM 预热) | <50ms |
| 匹配能力 | 谓词引擎(灵活但复杂) | URL/Header/Body 匹配 | URL/Header/Body/Diff |
我的选型建议
- 多协议混用场景 → 直接选 Mountebank,别犹豫。它的谓词匹配虽然重,但能覆盖 TCP 和 SMTP。
- Java 技术栈 + 已有 WireMock 团队经验 → 继续用 WireMock。它的录制稳定性和社区支持最好,出了问题能找到人问。
- 纯 HTTP 服务 + 追求极简 CI → Hoverfly。我推荐给两个 Serverless 项目都成功了,反馈说“再也不用在 Pipeline 里装 JDK 了”。
- 需要 gRPC Mock → 目前这三个都还不算成熟。Hoverfly 有实验性支持,但我在项目中还没敢上生产。可以关注
grpc-mock或grpc-fallback方案。
个人小技巧: 如果你的 CI 流水线里有多套环境(如 staging / prod 回放),可以考虑用 WireMock 做录制,然后用 Hoverfly 做回放——因为 WireMock 录制出来的 mapping 格式是 JSON,Hoverfly 可以读取 JSON 并转换为自己的格式。我写过一个转换脚本,后面有空可以分享出来。
最后想说一点:不管你选哪个工具,记得在 CI 中验证 Mock 数据是否过期。我吃过一次亏,录制好的回放数据因为下游接口改了字段名,CI 一直绿但线上崩了。从那以后,我每周会手动触发一次“刷新录制”的 Pipeline 任务,确保回放数据和真实接口对齐。