用 Jest 进行 JavaScript 单元测试入门指南
Jest 是一个由 Facebook 开发的成熟 JavaScript 测试框架,支持多种应用程序和库。它提供零配置、自动检测测试文件和自动重载等功能。Jest 内置了强大的断言库,并能生成详细的代码覆盖率报告。Jest 支持模拟和间谍功能,便于在测试中隔离依赖代码。
Jest 简介Jest 是什么
Jest 是一个由 Facebook 开发的成熟 JavaScript 测试框架,最初作为 Facebook 的内部工具开发,后来开源并成为 JavaScript 生态系统中广泛使用的工具。Jest 支持多种 JavaScript 应用程序,包括前端和后端应用,以及 Node.js 和 React 应用。
Jest 的主要功能
- 零配置:Jest 可直接运行于项目中,无需复杂配置。
- 自动检测测试文件:Jest 可自动检测项目中的测试文件,无需手动指定测试文件路径。
- 自动重载:在没有配置的情况下,Jest 可自动重载测试文件,当代码更改时,快速执行测试。
- 断言库:Jest 内置了强大的断言库,支持多种匹配方式。
- 测试覆盖率:Jest 可生成详细的代码覆盖率报告,帮助开发者理解哪些部分代码被测试覆盖。
- Mock 和 Spies:Jest 支持模拟和间谍功能,便于在测试中隔离依赖代码。
为什么选择 Jest
- 易于使用:Jest 提供简洁的 API,使得编写测试变得简单。
- 强大的功能:除了基本的单元测试,Jest 还支持集成测试、模拟依赖、异步测试等高级功能。
- 广泛的生态系统:Jest 与许多流行的框架和库(如 React、Vue、Angular)无缝集成。
- 社区支持:Jest 有一个活跃的社区,社区成员可以提供帮助并贡献功能。
- 文档丰富:Jest 的官方文档详细且易于理解,提供了大量的示例和教程。
- 测试覆盖率:Jest 提供详尽的测试覆盖率分析,帮助开发者识别未覆盖的代码区域。
示例项目
假设我们正在构建一个简单的计算器应用,使用 Jest 进行单元测试。这将展示 Jest 在实际项目中的应用。
安装和配置 Jest使用 npm 或 yarn 安装 Jest
安装 Jest 时,可以通过 npm 或 yarn 安装。以下是使用 npm 安装 Jest 的示例:
npm install --save-dev jest
或者使用 yarn:
yarn add --dev jest
安装完成后,Jest 将作为开发依赖项添加到 package.json
文件中。同时,node_modules
目录中会包含 Jest 及其依赖项。
配置 Jest 项目
Jest 通常不需要配置,但可以根据项目需求进行自定义。Jest 的配置可以通过在项目根目录下创建 jest.config.js
文件来实现。以下是一个简单的 jest.config.js
示例:
module.exports = {
// 测试文件的根目录
roots: ['<rootDir>/src'],
// 测试文件的扩展名
testMatch: ['**/?(*.)+(spec|test).js'],
// 用于设置全局的变量
setupFiles: ['<rootDir>/jest.setup.js'],
// 自定义的覆盖报告文件名
coverageReporters: ['text', 'lcov'],
// 是否使用 TypeScript
transform: {
'^.+\\.ts?$': 'ts-jest',
},
};
初始化 Jest 测试
初始化 Jest 测试时,可以在项目中创建测试文件夹并编写测试文件。通常,测试文件夹命名为 __tests__
或 tests
,并在其中编写测试文件。
mkdir __tests__
在 __tests__
文件夹中创建一个测试文件 example.test.js
:
// __tests__/example.test.js
const add = (a, b) => a + b;
describe('add function', () => {
it('should add two numbers', () => {
expect(add(1, 2)).toBe(3);
});
});
使用命令行运行测试:
npx jest
这样,你就可以通过 npx jest
命令来运行测试了。
创建测试文件
可以使用任何命名约定来组织测试文件,但通常推荐将测试文件放在 __tests__
或 tests
文件夹中。例如:
mkdir __tests__
在 __tests__
文件夹中创建一个测试文件 math.test.js
:
// __tests__/math.test.js
const { add, subtract } = require('../src/math');
describe('math operations', () => {
it('should add two numbers', () => {
expect(add(2, 3)).toBe(5);
});
it('should subtract second number from first', () => {
expect(subtract(5, 2)).toBe(3);
});
});
注意,测试文件通常以 .test.js
或 .spec.js
为扩展名。
使用 describe
, it
, 和 expect
describe
用于定义测试组,it
用于编写具体的测试用例,expect
用于编写断言。
// __tests__/example.test.js
describe('Example Suite', () => {
it('should test equality', () => {
expect(1 + 1).toBe(2);
});
it('should test inequality', () => {
expect(1 + 1).not.toBe(3);
});
});
测试函数和类的基本方法
例如,假设有一个简单的 Calculator
类:
// src/calculator.js
class Calculator {
add(a, b) {
return a + b;
}
subtract(a, b) {
return a - b;
}
}
可以为其编写测试:
// __tests__/calculator.test.js
const { Calculator } = require('../src/calculator');
describe('Calculator', () => {
it('should add two numbers', () => {
const calc = new Calculator();
expect(calc.add(2, 3)).toBe(5);
});
it('should subtract second number from first', () => {
const calc = new Calculator();
expect(calc.subtract(5, 2)).toBe(3);
});
});
Jest 的高级功能
使用 mock 和 spies
Mock 函数
Mock 函数用于模拟依赖项或外部调用。例如,假设有一个 fetchData
函数,它依赖于另一个函数 getData
:
// src/data.js
const getData = () => {
return 'data';
};
const fetchData = () => {
return getData();
};
module.exports = {
fetchData,
};
在测试中可以 mock getData
函数:
// __tests__/data.test.js
const { fetchData } = require('../src/data');
describe('fetchData', () => {
it('should fetch data using mock', () => {
jest.mock('../src/data', () => ({
getData: () => 'mocked data',
}));
expect(fetchData()).toBe('mocked data');
});
});
Spies
Spy 函数用于监视和断言函数的调用。例如:
// __tests__/spy.test.js
describe('Spy example', () => {
const spy = jest.fn();
it('should call the spy', () => {
spy();
expect(spy).toHaveBeenCalled();
});
});
测试异步代码
测试异步代码时,可以使用 async/await
、Promise
或 Jest 提供的 done
回调。
// src/promise.js
const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
module.exports = delay;
在测试中:
// __tests__/promise.test.js
const delay = require('../src/promise');
describe('delay', () => {
it('should resolve after the given delay', async () => {
const result = await delay(200);
expect(result).toBeUndefined();
});
it('should resolve using done', (done) => {
delay(200).then(() => {
expect(1).toBe(1);
done();
});
});
});
断言和匹配器
Jest 内置了许多匹配器,可以用来断言测试结果。例如:
// __tests__/assertions.test.js
describe('Assertions', () => {
it('should use toBe for equality', () => {
expect(1 + 1).toBe(2);
});
it('should use toBeNull for null', () => {
expect(null).toBeNull();
});
it('should use toBeDefined for not undefined', () => {
expect('hello').toBeDefined();
});
it('should use toBeTruthy for truthy values', () => {
expect('hello').toBeTruthy();
});
it('should use toBeFalsy for falsy values', () => {
expect(0).toBeFalsy();
});
});
此外,还提供了 toBeCloseTo
、toContain
、toEqual
、toThrow
等匹配器,可以用于不同的断言场景。
在终端中运行测试
在终端中,可以通过 npx jest
命令运行测试。例如:
npx jest
Jest 将会自动检测项目中的测试文件并运行测试。测试输出将显示在终端中,包括通过的测试、失败的测试以及覆盖率报告。
查看测试覆盖率
Jest 提供了详细的代码覆盖率报告。可以在 package.json
文件中添加 coverageReporters
配置来设置覆盖率报告的格式。例如:
{
"scripts": {
"test": "jest",
"coverage": "jest --coverage"
},
"jest": {
"coverageReporters": ["text", "lcov"]
}
}
运行 npm run coverage
或 yarn coverage
后,Jest 将生成覆盖率报告。默认情况下,报告会被输出到 coverage
文件夹中。
调试测试代码
为了调试测试代码,可以使用 debugger
关键字插入断点。例如:
// __tests__/debug.test.js
describe('Debugging Example', () => {
it('should debug a test', () => {
const a = 1;
debugger;
expect(a).toBe(1);
});
});
运行测试时,调试器会在断点处暂停。可以使用调试工具来检查变量状态、调用堆栈等,以便更好地理解测试行为。
总结和资源推荐Jest 学习资源
- 官方文档:Jest 官方文档是学习 Jest 最权威的资源。
- 慕课网:慕课网提供了多个关于 Jest 的课程,涵盖从基础到高级的各种知识点。
- GitHub:GitHub 上有许多 Jest 的示例项目,可以参考这些项目了解实际应用。
Jest 社区和文档
- Jest GitHub:Jest 的 GitHub 仓库包含了大量的文档和示例代码。
- Stack Overflow:Stack Overflow 上有很多关于 Jest 的问题和解答,可以作为参考。
- Jest 官方论坛:Jest 官方论坛是一个活跃的社区,可以提问问题并分享经验。
常见问题解答
为什么某些测试用例失败?
- 检查测试用例:确保测试用例正确地模拟了预期的行为。
- 检查实际代码:确保实际代码按预期实现了功能。
如何提高测试覆盖率?
- 编写更多的测试用例:覆盖更多的代码路径。
- 使用 Jest 的覆盖率报告:分析覆盖率报告,找到未覆盖的代码区域。
Jest 是否支持 TypeScript?
- 支持:Jest 支持 TypeScript,但需要安装
ts-jest
插件来正确处理 TypeScript 文件。
测试异步代码的最好方法是什么?
- 使用
async/await
:这是处理异步代码的推荐方法。Jest 自动支持async/await
测试用例。
通过以上内容,你已经掌握了如何使用 Jest 进行 JavaScript 单元测试的基本知识和高级功能。希望能帮助你在项目中应用 Jest 来提高代码质量。
共同学习,写下你的评论
评论加载中...
作者其他优质文章