高内聚的单元测试要求每个测试用例聚焦单一行为、命名直述意图、采用数据驱动、隔离外部依赖。例如用 test.each 验证多组输入,以 describe 分组行为,mock 掉 i/o,使测试快、稳、可维护。

高内聚的单元测试不是指测试用例之间强耦合,而是指每个测试用例紧密围绕一个明确、单一的行为展开,逻辑聚焦、边界清晰、不牵扯无关职责。它让测试本身成为可读、可定位、可独立维护的“行为说明书”,从而显著提升长期可维护性。
聚焦单个行为,避免测试用例膨胀
一个测试函数(test 或 it)只验证一种输入场景下的一种预期结果。例如验证邮箱格式校验,就只测格式错误时抛错、正确时返回 true,不同时混入数据库保存或发送通知的逻辑。
- ✅ 好做法:用
describe分组同类行为,再用多个test覆盖不同分支 - ❌ 避免:在一个
test里连续调用createUser、updateProfile、sendEmail并断言全部结果 - 例子:对
parseDate(str),分别写test('returns null for invalid string')、test('parses "2023-01-01" to Date object')
测试命名直述意图,不描述实现
名称应说明“它应该做什么”,而不是“它怎么做的”。这样即使函数内部重构,只要行为不变,测试名依然准确,无需修改。
- ✅ 推荐:
test('converts empty string to empty array')、test('throws when rate exceeds 1') - ❌ 不推荐:
test('calls filter() then map()')、test('uses regex pattern /^\d+$/') - 命名清晰后,新成员扫一眼测试列表就能掌握模块契约,相当于活文档
数据驱动测试,减少重复样板
对同一函数的多组输入输出,用 test.each 或数组遍历统一组织,避免复制粘贴测试结构。既压缩代码量,又确保所有用例执行相同断言逻辑。
- 例如验证
isEven(n),可写: test.each([[0, true], [1, false], [-2, true], [99, false]])('isEven(%i) returns %s', (input, expected) => { expect(isEven(input)).toBe(expected); });- 新增边界值只需加一行数据,不改逻辑,不易遗漏或出错
隔离外部依赖,让测试真正“单元”
单元测试必须快、稳、可重复。任何真实 I/O(HTTP 请求、数据库、Date.now()、Math.random())都需替换为可控模拟。这不是为了“绕过问题”,而是守住测试的单元属性。
- 用参数注入时间:把
now = () => new Date()作为函数参数,测试时传入固定日期 - 用 mock 函数替代副作用:如
saveUser(user, saveFn = api.save),测试中传jest.fn() - 避免在测试中启动 Express 服务、连接 MongoDB 或等待定时器——那已属集成测试范畴
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











