Jest 单元测试入门与进阶:mock、异步和快照测试

Sarah Wong | 2026-08-27T20:54:45 | JavaScript

系统讲解 Jest 测试框架的核心功能,包括 mock 函数、异步测试、快照测试和覆盖率报告的配置。

# Jest 单元测试入门与进阶 ## 安装 ```bash npm install -D jest @types/jest ts-jest ``` ## 基础测试 ```javascript // utils/math.js function add(a, b) { return a + b; } function multiply(a, b) { return a * b; } module.exports = { add, multiply }; // utils/math.test.js const { add, multiply } = require('./math'); describe('数学工具函数', () => { test('add: 1 + 2 = 3', () => { expect(add(1, 2)).toBe(3); }); test('multiply: 3 * 4 = 12', () => { expect(multiply(3, 4)).toBe(12); }); test('add: 处理负数', () => { expect(add(-1, -2)).toBe(-3); }); }); ``` ## Mock 函数 ```javascript // services/userService.js const db = require('./database'); async function getUserById(id) { const user = await db.query('SELECT * FROM users WHERE id = ?', [id]); if (!user) throw new Error('User not found'); return { id: user.id, name: user.name, email: user.email }; } // services/userService.test.js const db = require('./database'); const { getUserById } = require('./userService'); jest.mock('./database'); describe('getUserById', () => { afterEach(() => { jest.clearAllMocks(); }); test('返回格式化的用户对象', async () => { db.query.mockResolvedValue({ id: 1, name: '张三', email: 'zhang@test.com', password: 'hashed' }); const user = await getUserById(1); expect(db.query).toHaveBeenCalledWith( 'SELECT * FROM users WHERE id = ?', [1] ); expect(user).toEqual({ id: 1, name: '张三', email: 'zhang@test.com' }); // 确保密码没有泄漏 expect(user.password).toBeUndefined(); }); test('用户不存在时抛出错误', async () => { db.query.mockResolvedValue(null); await expect(getUserById(999)).rejects.toThrow('User not found'); }); }); ``` ## 异步测试 ```javascript // 方式一:返回 Promise test('fetchData 返回正确数据', () => { return fetchData().then(data => { expect(data).toBe('peanut butter'); }); }); // 方式二:async/await(推荐) test('fetchData 返回正确数据', async () => { const data = await fetchData(); expect(data).toBe('peanut butter'); }); // 方式三:回调函数 test('fetchData 回调返回数据', (done) => { fetchData((data) => { expect(data).toBe('peanut butter'); done(); }); }); ``` ## 快照测试 ```javascript const renderer = require('react-test-renderer'); const Button = require('./Button'); test('Button 组件渲染正确', () => { const tree = renderer.create( ).toJSON(); expect(tree).toMatchSnapshot(); }); // 第一次运行自动生成快照文件 // 后续运行会对比差异,变化时需要 jest --updateSnapshot 确认 ``` ## 覆盖率配置 ```json { "jest": { "collectCoverage": true, "coverageThreshold": { "global": { "branches": 80, "functions": 80, "lines": 80, "statements": 80 } } } } ``` 运行 `jest --coverage` 生成报告,关注分支覆盖率,它最能反映测试质量。

← Back to Blog