首页/开发/软件测试速查/测试替身(Test Doubles)
测试基础与分层67 条

测试替身(Test Doubles)

用替代对象替换真实依赖以便隔离测试:Dummy、Stub、Spy、Mock、Fake 五类各有用途;Martin Fowler 与 xUnit Patterns 均有系统论述。

软件测试速查开发更新于 2026-10-13

测试替身是什么

测试替身(Test Doubles)是用替代对象顶替真实依赖、让测试隔离运行的一类手段的总称——命名借自影视替身。Martin Fowler 与《xUnit Test Patterns》把它细分为五类:Dummy、Stub、Spy、Mock、Fake,各有明确职责。选对替身类型是用得稳的关键:验证状态用 Stub 与 Fake,只有需要验证交互协议时才上严格的 Mock。

五类替身

类型作用
Dummy仅填充参数,不被使用
Stub返回预设值,不校验交互
Spy记录调用信息供断言
Mock预设期望并校验调用
Fake简化可用的真实实现(如内存库)

基本信息

提出与整理Martin Fowler 与 Gerard Meszaros(xUnit Test Patterns)
选择原则优先 Fake 与 Stub 保持稳定;验证交互时才用 Mock
常见实现Mockito(Java)、unittest.mock(Python)、jest.fn(前端)
适用边界外部服务、时间、随机数、文件系统等不可控因素
反模式信号替身越写越多、重构时测试大面积失败

按需选择替身

按需选择替身
# 场景一:只想让依赖返回固定值——用 Stub
# 场景二:想验证「是否调用了支付接口、调用了几次」——用 Mock/Spy
# 场景三:需要一套可用的简化实现(如内存版仓库)——用 Fake
# 原则:先问测试要验证的是结果还是交互,再选类型

典型使用场景

  • 隔离外部服务:支付、短信、邮件等第三方不参与单元测试。
  • 固定时间与随机:冻结时钟、固定随机种子,让断言可重复。
  • 构造异常分支:用 Stub 返回超时、错误码等真实环境难造的场景。
  • 验证交互协议:确认下游被按约定调用,次数与参数正确。
  • 加速测试:用内存 Fake 替换慢速数据库或网络依赖。
  • 遗留代码改造:先替身隔离,建立安全网后再重构。
优先使用 Fake 与 Stub 保持用例稳定;只在验证交互协议时使用严格 Mock。
替身数量是设计信号:一个用例要配置七八个替身,通常说明被测对象职责过多,先考虑拆接口再测试。
Fake 要写自己的契约测试:内存实现的期望行为与真实依赖对齐,Fake 与真实实现的偏差是隐蔽的假通过来源。

易错点

  • 对每层依赖都打 Mock:测试通过只证明 Mock 配置正确,真实集成问题全被隔离掉。
  • Mock 预设了实现细节:重构时测试大面积失败,测试成了改造成本。
  • Stub 返回与真实类型不符的数据:边界条件差一位,缺陷在集成时才发现。
  • Fake 不与真实依赖对齐:内存库与数据库行为差异导致「测试全绿、环境全崩」。
  • 把所有替身都叫 Mock:团队沟通时概念混淆,选型讨论无从谈起。

数据来源与参考

  • Martin Fowler《TestDouble》《Mocks Aren't Stubs》(martinfowler.com)
  • Gerard Meszaros《xUnit Test Patterns》
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌