测试替身是什么
测试替身(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 与真实实现的偏差是隐蔽的假通过来源。