JavaScript单元测试之Jasmine详细介绍
December 1, 2024
Jasmine 框架详细介绍
Jasmine 是一个功能强大的 JavaScript 测试框架,特别适用于行为驱动开发(BDD)的测试风格。Jasmine 提供了开箱即用的断言库、Mock 功能和异步支持,无需额外依赖工具,适合测试 Node.js 和浏览器环境中的代码。
以下是 Jasmine 框架的详细讲解,包括安装、配置、基本用法和高级技巧。
1. Jasmine 的特点
- 独立性强:Jasmine 不依赖其他库,内置断言和 Mock 功能。
- 支持 BDD 测试风格:以
describe
和it
的方式组织测试。 - 异步支持:内置异步测试方法,如
done
和async/await
。 - 浏览器和 Node.js 兼容:可以在前后端通用。
- 快照和 Mock:自带简单易用的 Mock 工具。
2. 安装与配置
(1) 安装 Jasmine
在项目中安装 Jasmine:
npm install --save-dev jasmine
(2) 初始化项目
运行以下命令,生成 Jasmine 的配置文件:
npx jasmine init
生成的文件结构:
spec/
helpers/
jasmine.json # 配置文件
(3) 配置文件
jasmine.json
的内容:
{
"spec_dir": "spec", // 测试文件目录
"spec_files": ["**/*[sS]pec.js"], // 测试文件匹配规则
"helpers": ["helpers/**/*.js"] // 辅助文件目录
}
3. 基本用法
(1) 编写测试
被测试代码:calculator.js
function add(a, b) {
return a + b;
}
function subtract(a, b) {
return a - b;
}
module.exports = { add, subtract };
测试代码:calculator.spec.js
const { add, subtract } = require('../src/calculator');
describe('Calculator', () => {
it('should return 5 when adding 2 and 3', () => {
expect(add(2, 3)).toBe(5);
});
it('should return 1 when subtracting 3 from 4', () => {
expect(subtract(4, 3)).toBe(1);
});
});
运行测试:
npx jasmine
输出:
Calculator
✓ should return 5 when adding 2 and 3
✓ should return 1 when subtracting 3 from 4
(2) 组织测试
Jasmine 提供 describe
和 it
来组织测试用例:
describe
:用于分组测试用例。it
:定义单个测试。
示例:
describe('Math Operations', () => {
describe('Addition', () => {
it('should add two numbers correctly', () => {
expect(1 + 2).toBe(3);
});
});
describe('Subtraction', () => {
it('should subtract two numbers correctly', () => {
expect(5 - 3).toBe(2);
});
});
});
4. 断言
Jasmine 提供丰富的断言方法:
(1) 基本匹配
expect(4).toBe(4); // 严格相等
expect(4).not.toBe(5); // 不相等
expect({ a: 1 }).toEqual({ a: 1 }); // 深度相等
(2) 数字匹配
expect(10).toBeGreaterThan(5);
expect(5).toBeLessThan(10);
expect(0.1 + 0.2).toBeCloseTo(0.3, 5); // 浮点数比较
(3) 字符串匹配
expect('hello world').toContain('hello');
expect('JavaScript').toMatch(/script/i);
(4) 异常捕获
const throwError = () => { throw new Error('error'); };
expect(() => throwError()).toThrow();
expect(() => throwError()).toThrowError('error');
5. 异步测试
(1) 使用 done
回调
Jasmine 提供 done
回调来支持异步代码:
it('should fetch data', (done) => {
setTimeout(() => {
expect(1 + 1).toBe(2);
done();
}, 100);
});
(2) 使用 async/await
推荐使用现代 async/await
语法:
it('should fetch data asynchronously', async () => {
const data = await Promise.resolve('data');
expect(data).toBe('data');
});
6. Mock 功能
Jasmine 内置简单的 Mock 工具,用于模拟函数或依赖。
(1) Mock 函数
const mockFn = jasmine.createSpy('mockFn');
mockFn(1, 2);
expect(mockFn).toHaveBeenCalled();
expect(mockFn).toHaveBeenCalledWith(1, 2);
(2) 替换真实函数
const obj = {
fetchData: () => 'real data',
};
spyOn(obj, 'fetchData').and.returnValue('mocked data');
expect(obj.fetchData()).toBe('mocked data');
expect(obj.fetchData).toHaveBeenCalled();
(3) 异步 Mock
spyOn(obj, 'fetchData').and.returnValue(Promise.resolve('mocked async data'));
obj.fetchData().then((data) => {
expect(data).toBe('mocked async data');
});
7. 钩子函数
Jasmine 提供生命周期钩子来管理测试执行顺序:
beforeAll
:在所有测试之前运行一次。afterAll
:在所有测试之后运行一次。beforeEach
:在每个测试之前运行。afterEach
:在每个测试之后运行。
示例:
describe('Database Tests', () => {
beforeAll(() => {
console.log('Connect to database');
});
afterAll(() => {
console.log('Disconnect from database');
});
beforeEach(() => {
console.log('Start a transaction');
});
afterEach(() => {
console.log('Rollback transaction');
});
it('should insert data', () => {
expect(1).toBe(1);
});
it('should delete data', () => {
expect(2).toBe(2);
});
});
8. 快照测试
Jasmine 支持手动实现快照测试,但需要结合其他工具(例如 Jest 更适合快照)。
9. 浏览器环境测试
Jasmine 也可以用于浏览器环境,使用 Jasmine 的 HTML 报告工具。
- 下载 Jasmine Standalone: Jasmine GitHub Releases
- 解压后,修改
SpecRunner.html
文件,添加测试脚本。
10. 调试与优化
(1) 跳过或专注测试
- 跳过测试:使用
xit
或xdescribe
。 - 专注测试:使用
fit
或fdescribe
。
示例:
xdescribe('Skipped Tests', () => {
it('this test will not run', () => {
expect(true).toBe(false);
});
});
fdescribe('Focused Tests', () => {
it('this test will run', () => {
expect(true).toBe(true);
});
});
(2) 控制测试超时
默认超时时间是 5 秒,可以通过以下方法修改:
jasmine.DEFAULT_TIMEOUT_INTERVAL = 10000; // 10 秒
11. 最佳实践
- 测试独立性:每个测试用例应相互独立,避免共享状态。
- 简洁清晰:测试描述(
describe
和it
)应清楚表达预期行为。 - 集成到 CI/CD:将 Jasmine 测试集成到 CI/CD 流程中,确保代码质量。
- 结合工具:与 Karma、Protractor 等工具结合,适用于复杂的前端测试场景。
12. 推荐资源
- 官方文档:Jasmine 官方网站
- GitHub 仓库:Jasmine GitHub