测试驱动开发遵循红-绿-重构循环:先写失败测试(红),再实现代码通过测试(绿),最后优化代码结构。使用Jest可高效编写单元测试,支持断言、异步测试、模拟和覆盖率分析,提升代码质量与可维护性。

测试驱动开发(TDD)是一种以测试为先导的软件开发方式。在编写实际功能代码之前,先编写单元测试用例,再通过实现代码让测试通过。Jest 是一个由 Facebook 开发的 JavaScript 测试框架,因其简单易用、功能强大,广泛应用于 React 项目和 Node.js 服务中。本文将介绍如何在 TDD 实践中使用 Jest 编写高质量的单元测试。
理解 TDD 的基本流程
TDD 遵循“红-绿-重构”的循环模式:
-
红(Red):先编写一个失败的测试用例,验证期望行为尚未实现
-
绿(Green):编写最简代码使测试通过
-
重构(Refactor):优化代码结构,同时确保测试仍然通过
这种流程有助于保持代码简洁、可维护,并确保每一部分都有对应的测试覆盖。
配置 Jest 环境
在项目根目录初始化 npm 并安装 Jest:
npm init -y
npm install --save-dev jest
在 package.json 中配置测试命令:
"scripts": {
"test": "jest",
"test:watch": "jest --watch"
}
如果测试文件使用 ES6 模块语法(import/export),需配置 Babel 或使用 Node.js 原生支持,或改用 .cjs 扩展名。对于大多数现代项目,推荐结合 babel-jest 使用。
编写第一个单元测试
假设我们要实现一个简单的加法函数 sum(a, b)。按照 TDD 步骤,先写测试:
// sum.test.js
const sum = require('./sum');
test('adds 1 + 2 to equal 3', () => {
expect(sum(1, 2)).toBe(3);
});
运行 npm test,测试会失败(红阶段)。接着创建 sum.js 文件并实现函数:
// sum.js
const sum = (a, b) => a + b;
module.exports = sum;
再次运行测试,应显示通过(绿阶段)。此时可以进入重构环节,比如增强参数校验,同时保证测试仍通过。
使用 Jest 的核心断言与匹配器
Jest 提供丰富的 expect 匹配器来验证各种结果:
-
toBe(value):严格相等(===)
-
toEqual(value):深度比较对象或数组
-
toBeDefined():检查值不为 undefined
-
toBeTruthy() / toBeFalsy():检查真假值
-
toContain(item):检查数组或字符串是否包含某项
-
toThrow():验证函数是否抛出异常
例如:
test('object assignment', () => {
const data = { one: 1 };
data.two = 2;
expect(data).toEqual({ one: 1, two: 2 });
});
test('throws on invalid input', () => {
expect(() => sum('a', 'b')).toThrow();
});
测试异步代码
Jest 支持 Promise 和 async/await 的测试。例如有一个异步获取用户信息的函数:
// fetchUser.js
const fetchUser = () =>
Promise.resolve({ id: 1, name: 'John' });
module.exports = fetchUser;
对应的测试写法:
// fetchUser.test.js
const fetchUser = require('./fetchUser');
test('should resolve user data', async () => {
const user = await fetchUser();
expect(user).toEqual({ id: 1, name: 'John' });
});
也可以使用 resolves 匹配器:
return expect(fetchUser()).resolves.toEqual({ id: 1, name: 'John' });
模拟(Mocking)函数与模块
在测试中,常需要隔离外部依赖,如 API 调用、数据库操作等。Jest 提供强大的 mocking 功能。
例如,有一个函数依赖于另一个函数 getPrice():
// checkout.js
const getPrice = require('./priceUtils');
const total = (count) => getPrice() * count;
module.exports = total;
测试时可模拟 getPrice 的返回值:
// checkout.test.js
const total = require('./checkout');
const getPrice = require('./priceUtils');
jest.mock('./priceUtils'); // 自动创建 mock
test('calculates total with mocked price', () => {
getPrice.mockReturnValue(10);
expect(total(5)).toBe(50);
});
覆盖率报告
Jest 可生成测试覆盖率报告。添加配置:
"scripts": {
"test:coverage": "jest --coverage"
}
运行后会在项目中生成 coverage 目录,打开 index.html 可查看每行代码的覆盖情况。建议设置最低阈值以保证质量:
// jest.config.js
module.exports = {
collectCoverageFrom: ['src/**/*.{js,jsx}'],
coverageThreshold: {
global: {
branches: 80,
functions: 80,
lines: 80,
statements: 80
}
}
};
基本上就这些。掌握 Jest 的基本用法并坚持 TDD 流程,能显著提升代码质量和开发效率。关键是养成“先写测试”的习惯,逐步构建稳健的应用程序。不复杂但容易忽略。
以上就是测试驱动开发实践_Jest单元测试编写指南的详细内容,更多请关注php中文网其它相关文章!