Jest是JavaScript生态中最省心的单元测试框架,开箱即用、零配置,Mock和快照功能成熟,对React/Vue/TS支持最稳;快速启动只需npm install --save-dev jest并配置package.json的"test"脚本。

Jest 不是“必须学”的单元测试框架,但它是目前 JavaScript 生态中最省心的选择——开箱即用、零配置就能跑,Mock 和快照功能成熟,对 React/Vue/TS 支持也最稳。
如何快速启动一个 Jest 测试环境
不需要全局安装,也不建议用 npm install -g jest。直接在项目里装依赖即可:
npm install --save-dev jest
然后在 package.json 的 scripts 里加一句:
"test": "jest"
接着创建一个测试文件,比如 sum.test.js:
立即学习“Java免费学习笔记(深入)”;
const sum = require('./sum');
test('adds 1 + 2 to equal 3', () => {
expect(sum(1, 2)).toBe(3);
});
运行 npm test 就能立刻看到结果。Jest 默认匹配 *.test.js 或 *.spec.js 文件,不用额外配 testMatch。
test 和 it 有什么区别?该用哪个
test 和 it 完全等价,都是 jest.fn() 的别名,源码里就是 it === test。选哪个纯看团队习惯或可读性偏好:
- 写行为描述时,
it('should handle empty input')更接近 BDD 风格 - 写断言逻辑时,
test('returns null when input is undefined')更直白 - 混用不报错,但同一项目里保持统一更利于维护
注意:不要用 describe 嵌套太多层,超过 3 层就容易让测试用例路径变模糊,比如 describe('when user is admin', () => { describe('and has premium role', () => { ... }) }) 这种结构不如拆成独立测试文件。
mock 函数怎么写才不会踩坑
Jest 的 jest.fn() 很方便,但常见错误是「只 mock 行为,没管返回值类型」:
- 如果被测函数本应返回 Promise,却用
jest.fn().mockReturnValue({ data: 1 }),后续.then()会报错 —— 正确做法是mockResolvedValue({ data: 1 }) - 想模拟抛错?用
mockRejectedValue(new Error('timeout')),而不是mockImplementation(() => { throw new Error() }),后者会让catch捕获不到(因为不是 Promise reject) - Mock 模块时,
jest.mock('./api')必须放在import语句之前,否则模块已被加载,mock 失效
另外,mockClear() 和 mockReset() 区别明显:mockClear() 只清调用记录,保留实现;mockReset() 连实现一起重置,适合每个测试前用 beforeEach(() => myFn.mockReset())。
expect 的链式断言为什么有时不生效
最常见的原因是忘了加 return 或 await。比如异步测试中写成:
test('fetches user', () => {
return fetchUser().then(data => expect(data.name).toBe('Alice'));
});
看起来没问题,但如果 fetchUser() 抛错,这个测试会直接失败而非进入 expect。更稳妥的是:
test('fetches user', async () => {
const data = await fetchUser();
expect(data.name).toBe('Alice');
});
或者用 resolves:
test('fetches user', () => {
return expect(fetchUser()).resolves.toHaveProperty('name', 'Alice');
});
注意:Jest 默认等待 5 秒超时,如果测试里有真实网络请求或定时器,务必用 jest.setTimeout(10000) 调整,否则容易误报超时失败。
真正难的不是写第一个 expect,而是判断哪些逻辑值得测、哪些该抽成独立函数再测。比如一个包含 3 层条件嵌套和 2 次 API 调用的事件处理函数,硬塞进单个 test 里只会让维护成本飙升——拆函数、分场景、用 mockImplementationOnce 控制不同返回,比堆砌断言重要得多。










