单元测试核心是明确“测什么、怎么测、为什么这么测”:只验证单个函数/方法在给定输入下的确定输出,不涉真实DOM、接口或全局状态;推荐Vitest,强调行为驱动、依赖注入mock、环境主动适配、覆盖率重质量轻数字。

JavaScript 中单元测试全景解析,核心是看清楚“测什么、怎么测、为什么这么测”三层逻辑,而不是堆砌工具或罗列 API。
DMap GL地图JSAPI(dmapgl)开发指南。用于编写、审查、调试 DMap 地图 API 代码,涵盖地图初始化、覆盖物渲染、图层管理、事件处理、控件交互等任务。当用户提及 dmap、dmapgl、jsapi‑gl 或相关地图开发需求时自动触发。
明确单元测试的边界和定位
单元测试只验证单个函数、方法或纯逻辑模块在给定输入下的输出行为。它不涉及真实 DOM 操作(除非模拟)、不调用真实接口、不依赖全局状态(如 Date.now()、Math.random())。重点在于:输入确定 → 行为可预期 → 输出可断言。比如一个 formatCurrency(amount) 函数,测试应覆盖正数、负数、零、小数、大数等场景,而不是检查它内部用了 Intl.NumberFormat 还是字符串拼接。
选对工具,但别被工具带偏节奏
Vitest 是当前最推荐的起点:启动快、零配置支持 ES Module 和 TypeScript、API 简洁(describe/it/expect),且原生集成覆盖率报告。Jest 仍广泛使用,但配置稍重;Mocha + Chai 更适合需要深度定制的团队。关键不是框架多强大,而是能否让开发者快速写出稳定、易读、易维护的测试用例。装完 Vitest 后,一条命令就能跑起来:
npm install -D vitest # package.json 中加:"test": "vitest"
写法上坚持“行为驱动”,而非“实现复刻”
避免以下典型误区:
- 断言私有方法是否被调用(如
mockFn.mock.calls.length === 1) - 测试中手动 new Date() 或直接读 localStorage
- 用
vi.mock()去 mock 被测模块自身的方法(这等于测 mock,不是测行为)
正确做法是:把副作用抽离成依赖项,测试时注入可控的 mock。例如,一个发送请求的函数:export const fetchUser = (api) => api.get('/user'); // 测试时传入 { get: vi.fn().mockResolvedValue({ id: 1 }) }
环境适配要主动,不能靠默认
单元测试运行在 Node.js 环境,默认没有 document、window 或 fetch。若测试涉及 DOM 操作(如组件渲染),需显式启用 JSDOM(Vitest 中通过 testEnvironment: 'jsdom' 配置);若用到 fetch,可用 whatwg-fetch 或 msw 拦截网络请求。不配环境就写 document.createElement,测试必报错——这不是代码问题,是执行上下文没对齐。
覆盖率只是辅助,不是目标
行覆盖率 80% 不代表质量高,可能全是 if 分支的空 else 块;而一个关键路径的边界值没覆盖,哪怕 95% 也存在风险。建议关注:
- 所有公开函数至少有一个基础用例
- 每个 if/else、switch case、try/catch 都有对应输入触发
- 错误路径(如参数非法、Promise reject、throw error)必须显式验证
真正有价值的单元测试,是改完代码后敢立刻 npm test 并相信结果的人,不是报表上数字好看却不敢动的老代码。

















