Skip to content

Mock 框架实践

基础入门:Mock 是什么 & 为什么学它

Mock 是测试中通过模拟外部依赖的行为来隔离测试环境的技术。它用预设的响应替代真实服务调用,让测试不依赖外部系统的可用性和状态。

Mock 的本质是「用假的服务换真的服务」,让测试完全可控、可重复、可预测。核心概念包括:

Mock 对象(模拟真实对象行为的替身)。

Stub(返回固定数据的简单模拟)。

Spy(记录调用信息用于验证)。

Fake(有简化逻辑的工作实现)。

理解这些概念的区别,才能在合适的场景选择合适的方案。Mock 不是简单的「造假」,而是一种测试设计策略。好的 Mock 能让测试更聚焦、更快速、更稳定,坏的 Mock 会让测试与真实情况脱节,带来虚假的安全感。学习 Mock 的关键是在「隔离依赖」和「保持真实性」之间找到平衡。

为什么测试开发要学 Mock

  • 面试高频考点:Mock 是测试开发岗位的基础技能,面试官会问如何处理外部依赖、如何设计 Mock 策略。
  • 提高测试效率:Mock 让测试不依赖外部服务,测试执行更快、更稳定,不会因为第三方服务挂掉而测试失败。
  • 覆盖异常场景:真实服务很难主动触发异常(超时、500 错误、格式异常),Mock 可以轻松模拟这些场景。
  • 隔离不可控依赖:第三方支付、短信网关、外部 API 等不可控服务,必须用 Mock 隔离才能保证测试稳定性。
  • 降低测试成本:调用真实服务可能产生费用(短信费、API 调用费),Mock 可以零成本无限次调用。

Mock vs 真实服务对比

什么时候用 Mock

适用场景:

第三方服务不可控(支付渠道、短信网关)。

服务不稳定或响应慢。

需要覆盖异常场景(超时、错误码)。

会产生真实费用或数据污染。

单元测试隔离依赖。

Mock 的优势:完全可控、响应快速、零成本、可重复。

Mock 的风险:与真实行为可能不一致、测试通过但生产失败。

什么时候用真实服务

适用场景:

核心业务链路验证。

集成测试和端到端测试。

预发布环境验证。

Mock 行为验证。

真实服务的优势:测试结果可信、能发现真实环境问题。

真实服务的劣势:依赖外部可用性、可能产生费用、响应可能慢、异常场景难以触发。

如何平衡 Mock 和真实服务

分层策略:

单元测试层,大量使用 Mock 隔离依赖。

集成测试层,部分 Mock 部分真实,验证服务间交互。

端到端测试层,尽量用真实服务,只 Mock 不可控的第三方。

预发布环境,全真实环境验证。

定期校验:开发阶段用 Mock 提效,但定期用真实服务验证 Mock 的有效性。

前置知识:学 Mock 前你需要会什么

  • 【必须掌握】HTTP 协议基础:请求方法、状态码、请求头响应头,这是接口 Mock 的基础。
  • 【必须掌握】测试基础:单元测试、集成测试的概念,测试隔离和依赖注入的理解。
  • 【建议掌握】编程基础:至少会一门编程语言(Python/Java/JavaScript),能编写测试代码。
  • 【建议掌握】接口测试经验:了解接口测试流程,理解请求和响应的结构。
  • 【不需要掌握】Mock 不需要精通后端开发,但理解服务架构有助于设计 Mock 策略。

零基础第一步:Mock 你的第一个接口

10 分钟快速体验:以 WireMock 为例,

第一步,下载 WireMock 的独立 jar 包。

第二步,启动 WireMock 服务,默认监听 8080 端口。

第三步,使用 curl 或 Postman 发送请求,创建一个 Mock 映射(请求路径和响应内容)。

第四步,访问 Mock 的接口,验证返回预设的响应。

这个练习让你理解 Mock 的基本原理:启动 Mock 服务 → 配置请求匹配规则 → 定义响应内容 → 测试代码访问 Mock 地址。完成这个练习后,你就迈出了 Mock 的第一步。

分阶段学习建议

第一阶段:理解 Mock 概念(目标:知道 Mock 是什么、为什么用)

学习内容:Mock 的定义和分类(Mock、Stub、Spy、Fake)、Mock 的应用场景、Mock 的优缺点和风险。

练习任务:用 WireMock 或 MockServer 创建一个简单的 Mock 接口,体验请求匹配和响应控制。

时间建议:2-3 天,每天 1-2 小时。

第二阶段:工具使用(目标:能用工具完成基本 Mock)

学习内容:主流 Mock 工具对比(WireMock、MockServer、Moco)、请求匹配规则(路径、方法、参数、请求体)、响应配置(状态码、响应体、延迟)、前端 Mock 工具(Playwright intercept、Cypress intercept)。

练习任务:为一个依赖第三方接口的业务场景搭建 Mock,覆盖正常和异常响应。

时间建议:1-2 周,每天 1-2 小时。

第三阶段:策略设计(目标:能设计合理的 Mock 策略)

学习内容:依赖分析和 Mock 边界划分、Mock 数据管理(版本化、场景化)、Mock 与真实服务的切换机制、录制回放(Record and Replay)。

练习任务:为一个完整业务链路设计 Mock 策略,确定哪些服务用 Mock、哪些用真实服务,搭建可切换的测试环境。

时间建议:2-3 周,结合实际项目。

第四阶段:进阶应用(目标:能处理复杂的 Mock 场景)

学习内容:契约测试(Contract Testing)与 Mock 结合、Mock 在微服务测试中的应用、Mock 服务的高可用和一致性、Mock 治理平台搭建。

练习任务:实践契约测试,使用 Pact 或类似工具确保服务间接口契约的一致性。

时间建议:持续积累,结合实际项目。

时间投入建议

  • 每天 1-2 小时:约 2 周掌握基础工具使用,1 个月能独立设计 Mock 策略。
  • 每天 30 分钟:约 1 个月掌握基础,需要更长时间积累实践经验。
  • 建议:先完成阶段一和阶段二,然后在实际项目中实践阶段三和阶段四,边做边学效果最好。

学习资源推荐

  • WireMock 官方文档:功能全面,示例丰富,是最推荐的入门工具。
  • MockServer 官方文档:API 风格配置,适合 Java 技术栈。
  • 前端 Mock:Playwright 的 route.intercept 和 Cypress 的 cy.intercept 是前端测试首选。
  • 单元测试 Mock:Python 用 unittest.mock/pytest-mock,Java 用 Mockito,JavaScript 用 Jest。

实操案例:从流程理解真实应用

  • 案例 0:Mock 第一个接口(入门,10 分钟)
  • 案例 1:Mock Server 搭建(基础,理解场景设计)
  • 案例 2:契约测试(进阶,保证接口一致性)

案例 0:Mock 你的第一个接口

【难度】入门级,10 分钟完成

【场景】Mock 一个返回用户信息的接口,让测试不依赖真实用户服务

【步骤】

第一步:下载 WireMock jar 包,通过命令行启动(java -jar wiremock.jar)。

第二步:创建 mappings 目录,编写 Mock 映射文件,定义请求路径和方法、响应状态码和响应体。

第三步:启动测试脚本,将原请求地址改为 WireMock 地址。

第四步:验证测试通过,Mock 返回预设的响应数据。

【学到什么】理解 Mock 的基本流程:启动 Mock 服务 → 配置映射规则 → 测试代码访问 Mock 地址。理解请求匹配和响应配置的概念。

【下一步】尝试配置不同的响应(延迟响应、错误码),体验 Mock 对场景的完全控制。

案例 1:Mock Server 搭建

【难度】基础级,理解场景设计

【场景】为支付回调场景搭建 Mock Server,模拟支付成功、失败、超时等多种状态

【步骤】

第一步:分析支付回调接口文档,明确请求格式和响应要求。

第二步:设计 Mock 场景,包括支付成功、余额不足、网络超时、签名错误等。

第三步:编写 Mock 映射,使用请求体匹配和状态转换,让不同请求返回不同响应。

第四步:集成到测试环境,通过环境变量控制是否使用 Mock。

第五步:编写测试用例,覆盖各种支付状态的业务逻辑。

【关键要点】Mock 场景要覆盖正常和异常,Mock 数据要基于真实服务文档,Mock 服务要支持动态切换。

【下一步】尝试录制真实服务的响应,自动生成 Mock 数据。

案例 2:契约测试

【难度】进阶级,保证接口一致性

【场景】使用契约测试确保 Mock 与真实服务的一致性

【步骤】

第一步:理解契约测试概念,消费者定义期望的接口契约,提供者验证是否满足契约。

第二步:选择契约测试工具(如 Pact),在消费者测试中定义契约。

第三步:生成契约文件,发布到 Pact Broker 或共享位置。

第四步:在提供者测试中验证契约,确保真实服务满足消费者期望。

第五步:集成到 CI/CD,每次接口变更都自动验证契约。

【关键要点】契约测试解决了 Mock 与真实服务不一致的问题。消费者驱动的契约让 Mock 数据有据可依,契约验证让变更第一时间被发现。

【下一步】探索 Mock 治理平台,统一管理 Mock 数据和契约。

常见误区:初学者最容易踩的坑

误区 1:过度 Mock,测试与真实环境脱节

【错误表现】所有外部依赖都用 Mock,测试全过但上线就出问题。

【为什么错】Mock 的响应是预设的,可能与真实服务不一致。过度 Mock 让测试失去了验证真实集成的意义。

【正确做法】分层策略:单元测试可以用 Mock,集成测试减少 Mock 比例,端到端测试尽量用真实服务。核心业务链路必须用真实服务验证。

【面试应对】

面试时要说明:我们的测试策略是分层的,单元测试用 Mock 提效,但集成测试和预发布环境会用真实服务验证。

误区 2:Mock 数据不更新,与真实服务不一致

【错误表现】Mock 数据很久没有更新,真实接口已经改了,Mock 还在返回旧格式。

【为什么错】服务接口会迭代更新,Mock 数据不跟着更新会导致测试通过但生产失败。

【正确做法】建立 Mock 数据维护机制:基于接口文档自动生成 Mock、定期用真实服务校验 Mock 响应、接口变更时同步更新 Mock。

【面试应对】

面试时要说明:我们有 Mock 数据校验机制,定期用真实服务验证 Mock 的有效性,接口变更会同步更新 Mock。

误区 3:只 Mock 正常场景,忽略异常场景

【错误表现】Mock 只返回成功响应,没有覆盖超时、错误码、格式异常等场景。

【为什么错】真实服务会出问题,如果不测试异常场景,业务代码可能缺少容错处理。

【正确做法】Mock 要覆盖:成功响应(各种正常数据)、客户端错误(4xx)、服务端错误(5xx)、网络异常(超时、断连)、数据异常(格式错误、字段缺失)。

【面试应对】

面试时要说明:我们的 Mock 策略覆盖异常场景,包括超时、错误码、格式异常等,验证业务的容错能力。

误区 4:Mock 数据管理混乱,难以维护

【错误表现】Mock 数据散落各处,没有版本管理,改一个响应要找半天。

【为什么错】Mock 数据没有统一管理,维护成本高,容易出现不一致。

【正确做法】Mock 数据版本化管理,与测试代码同步提交。按场景组织 Mock 数据,便于查找和复用。环境配置分离,支持不同环境使用不同 Mock。

【面试应对】

面试时要说明:我们的 Mock 数据统一管理,有版本控制,按场景组织,支持多环境配置。

误区 5:不会区分 Mock、Stub、Spy 的使用场景

【错误表现】提到 Mock 就只知道 WireMock,不理解不同测试替身的适用场景。

【为什么错】不同场景需要不同的测试替身,选错工具会增加复杂度或降低测试价值。

【正确做法】Stub:只需要固定返回值时用,简单直接。Mock:需要验证交互(调用次数、参数)时用,功能更全。Spy:需要记录真实调用信息时用,介于真实和 Mock 之间。Fake:需要简化版实现时用,如内存数据库。

【面试应对】

面试时要能说清区别:Stub 只提供固定返回,Mock 还能验证交互行为,Spy 记录调用信息,Fake 有简化逻辑。

误区总结

  • 过度 Mock → 分层策略,核心链路用真实服务验证
  • Mock 数据不更新 → 建立校验机制,定期验证一致性
  • 只 Mock 正常场景 → 覆盖异常场景,验证容错能力
  • Mock 数据管理混乱 → 统一管理,版本控制,场景组织
  • 不会区分 Mock/Stub/Spy → 理解差异,选择合适的测试替身

面试问答:如何把知识讲清楚

Q1:什么是 Mock?为什么要用 Mock?【P0 高频】

【回答骨架】定义 → 核心作用 → 适用场景 → 风险

【深度答案】Mock 是测试中用模拟对象替代真实依赖的技术,核心目的是隔离测试环境,让测试可控、可重复、快速执行。

使用 Mock 的原因:

第一,隔离不可控的外部依赖(第三方服务、外部系统)。

第二,提高测试效率,不依赖外部服务的可用性。

第三,覆盖难以触发的异常场景(超时、错误码)。

第四,降低测试成本,避免调用真实服务产生费用。

【追问应对】

  • Mock 有什么风险?→ 可能与真实服务不一致,测试通过但生产失败,需要定期用真实服务校验。- 什么时候不用 Mock?→ 核心业务链路验证、集成测试、预发布环境,这些场景需要真实服务。

Q2:Mock、Stub、Spy 有什么区别?【P1 重要】

【回答骨架】概念定义 → 功能区别 → 适用场景

【深度答案】三者都是测试替身,但功能不同。

Stub(桩):最简单的测试替身,只返回预设的固定数据,不验证交互,适用于只需要固定返回值的场景。

Mock:功能更全面,既能返回预设响应,又能验证交互行为(是否调用、调用几次、传入什么参数),适用于需要验证交互的场景。

Spy(间谍):介于真实对象和 Mock 之间,记录真实调用信息但不改变行为,适用于需要验证真实行为的场景。

【追问应对】

  • 你项目里用哪个?→ 单元测试用 Stub/Mock,接口测试用 WireMock 这种 Mock Server。- 什么时候用 Spy?→ 需要记录真实调用信息但不完全 Mock 时用,比如验证日志是否被正确调用。

Q3:你用哪些 Mock 工具?怎么选择的?【P0 高频】

【回答骨架】工具分类 → 选择依据 → 项目实践

【深度答案】Mock 工具分三类:

第一类是独立 Mock Server(WireMock、MockServer),适合接口级 Mock,多语言通用,功能强大。

第二类是前端测试工具内置能力(Playwright route.intercept、Cypress cy.intercept),适合前端自动化,集成度高。

第三类是单元测试 Mock 库(Python unittest.mock、Java Mockito、JavaScript Jest),适合单元测试,与测试框架集成好。

选择依据:接口级 Mock 选独立 Mock Server(通用性强),前端测试选框架内置能力(集成度高),单元测试选语言原生 Mock 库(便捷性好)。

【追问应对】

  • WireMock 和 MockServer 怎么选?→ 功能类似,WireMock 文档更好,MockServer Java API 更友好。- 你实际用过哪个?→ 根据实际项目回答,能说清选择理由和使用场景。

Q4:如何保证 Mock 与真实服务的一致性?【P1 重要】

【回答骨架】问题分析 → 解决方案 → 实践经验

【深度答案】Mock 与真实服务不一致是 Mock 的最大风险,可能导致测试通过但生产失败。

保证一致性的方法:

第一,基于真实服务文档或录制数据生成 Mock,不凭空想象。

第二,定期用真实服务校验 Mock 响应,发现不一致及时修正。

第三,使用契约测试(如 Pact),让 Mock 数据有据可依。

第四,接口变更时同步更新 Mock,建立变更通知机制。

实践经验:开发阶段可以快速迭代 Mock,但集成测试和预发布环境必须用真实服务验证。

【追问应对】

  • 录制回放是什么?→ 用工具录制真实服务的请求响应,自动生成 Mock 数据,保证与真实服务一致。- 契约测试怎么做?→ 消费者定义期望契约,提供者验证是否满足,契约作为 Mock 的依据。

Q5:Mock 策略如何设计?什么时候用 Mock 什么时候用真实服务?【P0 高频】

【回答骨架】分层策略 → 判断原则 → 实践经验

【深度答案】Mock 策略的核心是在隔离依赖和保持真实性之间找到平衡。

分层策略:

单元测试层,大量使用 Mock 隔离依赖,提高测试速度和稳定性。

集成测试层,部分 Mock 部分真实,验证服务间交互。

端到端测试层,尽量用真实服务,只 Mock 不可控的第三方。

预发布环境,全真实环境验证。

判断原则:第三方不可控服务用 Mock(支付、短信、外部 API)。内部可控服务尽量用真实。核心业务链路必须用真实验证。异常场景用 Mock 模拟。

【追问应对】

  • 支付服务怎么处理?→ 开发和测试环境用 Mock,预发布和灰度用真实沙箱环境。- Mock 会影响测试覆盖率吗?→ 不影响,Mock 只是替代依赖,测试逻辑覆盖率不变。

面试回答的核心技巧

  • 讲清 Mock 的价值:不只是技术工具,更是测试策略的一部分,要说明什么时候用、什么时候不用。
  • 结合实际场景:准备 1-2 个具体案例,比如 Mock 支付回调、Mock 第三方登录,能说清为什么用 Mock、怎么设计 Mock。
  • 展示风险意识:主动提到 Mock 与真实服务不一致的风险,说明如何保证一致性,体现思考深度。
  • 区分工具类型:能说清 Mock Server、前端 Mock、单元测试 Mock 的区别和适用场景。
  • 强调分层策略:单元测试、集成测试、端到端测试的 Mock 比例不同,核心链路必须用真实服务验证。