关于 jest-testing
jest-testing 是帮助开发者使用 Jest 测试 Node.js 应用的技能,涵盖测试编写、模拟、API 测试和覆盖率。它从基础测试结构延伸到集成测试与 CI/CD。
主要功能
- 01编写单元测试与异步测试
- 02模拟模块和函数
- 03使用 Supertest 测试 API
- 04生成代码覆盖率报告
- 05配置测试生命周期钩子
适用场景
- 01为 Node.js 函数编写测试
- 02验证 API 端点行为
- 03模拟外部依赖以隔离测试
- 04在 CI/CD 流程中运行测试
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ pluginagentmarketplace/ custom-plugin-nodejs --skill jest-testing安装后在 Claude Code 中输入/jest-testing确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
assets/config.yamlreferences/GUIDE.mdscripts/helper.py详细介绍
Jest 测试技能
掌握使用 Jest 测试 Node.js 应用——这款令人愉悦的 JavaScript 测试框架。
快速开始
只需 3 步即可开始测试:
- 安装 -
npm install --save-dev jest supertest - 编写测试 - 创建
*.test.js文件 - 运行 -
npm test
核心概念
基本测试结构
// sum.test.js
const sum = require('./sum');
describe('sum function', () => {
test('adds 1 + 2 to equal 3', () => {
expect(sum(1, 2)).toBe(3);
});
test('adds negative numbers', () => {
expect(sum(-1, -2)).toBe(-3);
});
});
Jest 配置
// package.json
{
"scripts": {
"test": "jest",
"test:watch": "jest --watch",
"test:coverage": "jest --coverage"
},
"jest": {
"testEnvironment": "node",
"coverageThreshold": {
"global": {
"branches": 80,
"functions": 80,
"lines": 80
}
}
}
}
单元测试
// userService.test.js
const UserService = require('./userService');
const User = require('./models/User');
jest.mock('./models/User');
describe('UserService', () => {
beforeEach(() => {
jest.clearAllMocks();
});
describe('createUser', () => {
it('should create user successfully', async () => {
const userData = {
name: 'John',
email: '[email protected]'
};
User.create.mockResolvedValue({ id: 1, ...userData });
const result = await UserService.createUser(userData);
expect(User.create).toHaveBeenCalledWith(userData);
expect(result.id).toBe(1);
});
it('should throw error for duplicate email', async () => {
User.create.mockRejectedValue(new Error('Email exists'));
await expect(UserService.createUser({}))
.rejects
.toThrow('Email exists');
});
});
});
学习路径
初学者(1-2 周)
- ✅ 配置 Jest 并编写基础测试
- ✅ 理解测试结构(describe/it/expect)
- ✅ 学习匹配器(toBe、toEqual 等)
- ✅ 测试同步函数
中级(3-4 周)
- ✅ 测试异步函数
- ✅ 模拟模块和函数
- ✅ 使用 Supertest 进行 API 测试
- ✅ 生成代码覆盖率报告
高级(5-6 周)
- ✅ 集成测试
- ✅ 测试数据库操作
- ✅ CI/CD 集成
- ✅ 性能测试
使用 Supertest 进行 API 测试
const request = require('supertest');
const app = require('./app');
describe('User API', () => {
describe('POST /api/users', () => {
it('should create new user', async () => {
const userData = {
name: 'John',
email: '[email protected]',
password: 'password123'
};
const response = await request(app)
.post('/api/users')
.send(userData)
.expect('Content-Type', /json/)
.expect(201);
expect(response.body).toHaveProperty('id');
expect(response.body.email).toBe(userData.email);
});
it('should return 400 for invalid email', async () => {
const response = await request(app)
.post('/api/users')
.send({ email: 'invalid' })
.expect(400);
expect(response.body).toHaveProperty('error');
});
});
describe('GET /api/users/:id', () => {
it('should return user by id', async () => {
const response = await request(app)
.get('/api/users/123')
.expect(200);
expect(response.body.id).toBe('123');
});
it('should return 404 for non-existent user', async () => {
await request(app)
.get('/api/users/999')
.expect(404);
});
});
});
模拟模式
// Mock entire module
jest.mock('axios');
const axios = require('axios');
test('fetches data from API', async () => {
axios.get.mockResolvedValue({ data: { id: 1 } });
const result = await fetchUser(1);
expect(axios.get).toHaveBeenCalledWith('/api/users/1');
expect(result.id).toBe(1);
});
// Spy on function
test('calls callback', () => {
const callback = jest.fn();
processData('test', callback);
expect(callback).toHaveBeenCalledWith('test');
expect(callback).toHaveBeenCalledTimes(1);
});
// Mock timers
jest.useFakeTimers();
test('delays execution', () => {
const callback = jest.fn();
setTimeout(callback, 1000);
jest.advanceTimersByTime(1000);
expect(callback).toHaveBeenCalled();
});
测试生命周期钩子
describe('User Tests', () => {
beforeAll(async () => {
// Setup test database
await connectTestDB();
});
afterAll(async () => {
// Cleanup
await disconnectTestDB();
});
beforeEach(async () => {
// Clear data before each test
await User.deleteMany({});
});
afterEach(() => {
// Cleanup after each test
jest.clearAllMocks();
});
test('...', () => {});
});
Jest 匹配器
// Equality
expect(value).toBe(expected) // Strict equality (===)
expect(value).toEqual(expected) // Deep equality
expect(value).not.toBe(expected) // Negation
// Truthiness
expect(value).toBeDefined()
expect(value).toBeNull()
expect(value).toBeTruthy()
expect(value).toBeFalsy()
// Numbers
expect(value).toBeGreaterThan(3)
expect(value).toBeGreaterThanOrEqual(3)
expect(value).toBeLessThan(5)
expect(value).toBeCloseTo(0.3) // Floating point
// Strings
expect(string).toMatch(/pattern/)
expect(string).toContain('substring')
// Arrays
expect(array).toContain(item)
expect(array).toHaveLength(3)
// Objects
expect(obj).toHaveProperty('key')
expect(obj).toMatchObject({ key: 'value' })
// Exceptions
expect(() => fn()).toThrow()
expect(() => fn()).toThrow('error message')
// Async
await expect(promise).resolves.toBe(value)
await expect(promise).rejects.toThrow()
代码覆盖率
# Run with coverage
npm test -- --coverage
# Coverage report shows:
# - Statements: % of code executed
# - Branches: % of if/else paths
# - Functions: % of functions called
# - Lines: % of lines executed
测试最佳实践
- ✅ AAA 模式:准备、执行、断言
- ✅ 每项测试只进行一次断言(理想情况下)
- ✅ 使用描述性测试名称
- ✅ 测试边界情况
- ✅ 模拟外部依赖
- ✅ 在测试后进行清理
- ✅ 避免测试之间相互依赖
- ✅ 以 80% 以上的覆盖率为目标
CI/CD 集成
# .github/workflows/test.yml
name: Tests
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: 18
- run: npm ci
- run: npm test -- --coverage
- uses: codecov/codecov-action@v3
适用场景
以下情况适合使用 Jest 测试:
- 构建 Node.js 应用
- 需要全面的测试覆盖率
- 希望快速并行执行测试
- 需要模拟和快照测试
- 实施 CI/CD 流水线
相关技能
- Express REST API(测试 API 端点)
- 异步编程(测试异步代码)
- 数据库集成(测试数据库操作)
- JWT 身份验证(测试身份验证流程)
资源
评论
支持 Markdown