前端js单元测试应精准锁定业务不可妥协的行为契约,即影响用户关键操作、高复用高风险、有明确规则或历史故障的核心逻辑,并通过最小闭环测试“冻住”现状,聚焦可观察结果,解耦dom和mock,最终用可观测、可解释的验证确认重构未破坏原有行为。

前端代码重构时,JS 单元测试要真正“锁定核心功能”,关键不是多写测试,而是精准识别、隔离并固化那些**业务不可妥协的行为契约**。它不是覆盖所有分支,而是守住用户能感知、系统会崩掉、钱会算错的那几条命脉。
明确什么是“核心功能”——从用户和系统视角定义
核心功能不是代码里最复杂的函数,而是满足以下任一条件的逻辑:
- 直接影响用户关键操作结果(如“提交订单”最终生成的金额、优惠是否生效、库存是否扣减)
- 被多个模块调用且变更风险高(如统一的价格计算工具、权限校验钩子、表单验证规则集)
- 有明确业务规则约束(如“满299减30,但不与会员折扣同享”“退款金额不能超过实付”)
- 历史出过线上故障或频繁被改坏(查看线上错误日志、Git blame 高频修改记录)
用测试把核心行为“冻住”——红绿循环中的“守恒验证”
重构不是重写,是换壳不换魂。单元测试此时的作用是做“行为快照”:确保改完之后,输入相同,输出(含副作用)完全一致。
将一个或多个视频上传至YouTube。当用户想“上传到YouTube”“发YouTube”“批量上传”“upload to YouTube”“post videos to YouTube”或发布到YouTube时使用此技能。
- 对每个核心函数/方法,先补全“已知正确行为”的最小闭环测试:至少覆盖1个正常路径 + 1个边界值 + 1个典型异常(如空输入、超限值)
- 测试断言聚焦可观察结果:返回值、DOM状态变化、发出的API参数、触发的事件类型与载荷,而非内部实现细节(比如不测“调用了哪个私有辅助函数”)
- 遇到“旧逻辑有bug但已成事实”的情况(如某折扣计算长期少算0.01元),测试应先忠实复现该行为——先锁住现状,再单独开卡修复,避免重构中意外“修好”导致下游系统不兼容
避开重构期测试失效的陷阱
测试跑不起来,不等于代码坏了,很可能是测试本身耦合了不该耦合的东西:
- 删掉所有基于DOM选择器的断言(如expect(screen.getByText('删除')).toBeInTheDocument()),改用组件props输出、返回值或自定义事件验证;选择器变=测试脆,不是功能变
- 检查mock是否过度:只mock真实外部依赖(如API、localStorage、第三方SDK),不mock本模块内其他函数——否则你测的不是代码,是mock配置
- 若测试因this指向、strict mode报错失败(如Cannot assign to read only property 'length'),说明被测代码或测试辅助逻辑违反了运行时契约,这本身就是重构需清理的技术债,别绕开
重构完成后,用测试确认“没动错”
最后一步不是看测试全绿,而是看绿得有依据:
- 运行核心测试集时开启Jest的--detectOpenHandles和--verbose,确认无未清理的定时器、未关闭的Promise、意外的全局状态残留
- 对涉及异步或副作用的核心路径(如提交表单后跳转+上报埋点),用await waitFor等待真实状态,而非靠setTimeout硬等
- 比对重构前后同一组输入的快照(如组件render结果、API请求体结构),差异必须全部可解释且符合设计意图
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










