名称: 测试反模式 描述: 永远不要测试模拟行为。永远不要在生产类中添加仅用于测试的方法。在模拟之前理解依赖关系。 使用时机: 当编写或更改测试、添加模拟、或试图在生产代码中添加仅用于测试的方法时 版本: 2.0.0 渐进披露: 入口点: 摘要: “避免测试模拟、仅用于测试的生产方法和不完整的模拟。测试真实行为,而不是模拟行为。” 使用时机: “当编写测试、添加模拟、审查测试失败、或试图在生产代码中添加仅用于测试的方法时。” 快速开始: “1. 问:‘我在测试真实行为吗?’ 2. 检查:‘这个方法仅用于测试吗?’ 3. 验证:‘我理解我正在模拟的内容吗?’ 4. 确认:‘我的模拟完整吗?’ 5. 应用:TDD防止这些模式” 参考: - core-anti-patterns.md - completeness-anti-patterns.md - detection-guide.md - tdd-connection.md
测试反模式
概述
测试必须验证真实行为,而不是模拟行为。模拟是用来隔离的手段,而不是被测试的对象。
核心原则: 测试代码做什么,而不是模拟做什么。
遵循严格的TDD防止这些反模式。 参见测试驱动开发技能了解完整的TDD工作流。
使用时机
激活此技能当您:
- 编写或更改测试 - 验证您在测试真实行为
- 添加模拟 - 确保模拟是必要且正确的
- 审查测试失败 - 检查模拟行为是否是问题
- 试图添加仅用于测试的方法 - 停止并重新考虑
- 测试感觉过于复杂 - 过度模拟的迹象
铁律
1. 永远不要测试模拟行为
2. 永远不要在生产类中添加仅用于测试的方法
3. 永远不要在理解依赖关系之前模拟
4. 永远不要创建不完整的模拟
5. 永远不要将测试视为事后想法
核心反模式类别
1. 测试模拟行为
断言模拟元素而不是真实行为。修复: 测试真实组件或不模拟它。 → core-anti-patterns.md
2. 生产中的仅用于测试方法
生产类中仅由测试使用的方法。修复: 移到测试工具中。 → core-anti-patterns.md
3. 不理解依赖关系的模拟
模拟而不理解依赖关系或副作用。修复: 先理解,最小化模拟。 → core-anti-patterns.md
4. 不完整的模拟
部分模拟缺少下游代码需要的字段。修复: 镜像完整的API结构。 → completeness-anti-patterns.md
5. 测试作为事后想法
实现“完成”但没有测试。修复: TDD - 先写测试。 → completeness-anti-patterns.md
快速检测清单
在提交任何测试之前运行此清单:
□ 我是否在断言模拟元素?(testId='*-mock')
→ 如果是:停止 - 测试真实组件或取消模拟
□ 这个方法是否仅用于测试?
→ 如果是:停止 - 移到测试工具中
□ 我完全理解我正在模拟的内容吗?
→ 如果不是:停止 - 先用真实实现运行,然后最小化模拟
□ 我的模拟缺少真实API的字段吗?
→ 如果是:停止 - 镜像完整的API结构
□ 我是否在测试之前写了实现?
→ 如果是:停止 - 删除实现,先写测试(TDD)
□ 模拟设置是否超过50%的测试代码?
→ 如果是:考虑使用真实组件的集成测试
参见: detection-guide.md 了解全面的红色标志和警告信号。
底线
模拟是用来隔离的工具,而不是要测试的东西。
如果您在测试模拟行为,您已经出错了。修复:测试真实行为,或质疑为什么模拟。
TDD防止这些模式。 先写测试 → 观察失败 → 最小实现 → 通过 → 重构。
导航
详细反模式分析
检测与预防
相关技能
关键提醒
- 模拟隔离,不证明 - 测试真实代码,而不是模拟
- 生产忽略测试 - 没有仅用于测试的方法
- 模拟前理解 - 了解依赖关系和副作用
- 仅完整模拟 - 镜像完整的API结构
- 测试就是实现 - 不是可选的附件
红色标志 - 停止
立即停止如果您发现自己:
- 断言
*-mock测试ID - 添加仅在测试文件中调用的方法
- 模拟“只是为了安全”而不理解
- 从内存创建模拟而不是API文档
- 说“测试可以等”或“准备好测试”
当模拟变得太复杂时: 考虑使用真实组件的集成测试。通常更简单且更有价值。
与其他技能的集成
先决条件: 测试驱动开发 - TDD防止反模式 互补: 完成前验证 - 测试 = 完成 领域特定: webapp-testing, backend-testing 用于框架模式