给 React + TS 项目添加 Jest 测试
以 react + ts 的组件库项目为例,记录 jest 安装配置及测试的过程。
一、安装配置
安装 jest
npm install jest -D
生成配置文件
npx jest --init
按照引导进行选择后,会创建配置文件 jest.config.js
,并在 package.json
中添加命令脚本 test: jest
支持 babel
要想支持 ts 和 react,都需要先支持 babel,从而在测试环境中转换代码
npm install babel-jest @babel/core @babel/preset-env -D
// .babelrc
{
presets: [
[
'@babel/preset-env',
{
targets: {
node: 'current',
}
}
]
]
}
支持 ts
npm install @babel/preset-typescript -D
// .babelrc
{
presets: [
[
'@babel/preset-env',
{
targets: {
node: 'current',
}
}
],
'@babel/preset-typescript' // 添加这个
]
}
支持 react
npm install @babel/preset-react -D
// .babelrc
{
presets: [
[
'@babel/preset-env',
{
targets: {
node: 'current',
}
}
],
'@babel/preset-typescript'
'@babel/preset-react' // 添加这个
]
}
使用 react 测试工具 enzyme
添加 enzyme
npm install enzyme enzyme-adapter-react-16 -D
项目中新建 tests/jest.setup.js 文件
// jest.setup.js
import Enzyme from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
Enzyme.configure({ adapter: new Adapter() });
并在 jest.config.js 中配置
setupFiles: ['./tests/jest.setup.js']
二、快照测试
-
使用 react-test-renderer
添加 react-test-renderer
用于快照测试
npm install react-test-renderer -D
下面给 Button 组件添加测试试一下
// components/button/__test__/index.test.js
import React from 'react';
import renderer from 'react-test-renderer';
import Button from '../Button';
describe('Button 组件', () => {
it('正确渲染 Button 组件', () => {
const button = renderer.create(<Button>button</Button>).toJSON();
expect(button).toMatchSnapshot();
});
});
执行 npm run test
可以看到有一个快照被生成了
再执行一遍 npm run test
,这次没有写快照了,并且匹配通过了
-
也可以用 enzyme 来进行快照测试(推荐)
添加 enzyme-to-json
,用于将 enzyme 构造的 wrapper 转变成能够支持快照测试的格式。
npm install enzyme-to-json -D
同样,测试一下 Button 组件
// components/button/__test__/index.test.js
import React from 'react';
import Button from '../Button';
import { render } from 'enzyme';
import toJson from 'enzyme-to-json';
describe('Button 组件', () => {
it('正确渲染 Button 组件', () => {
const button = render(<Button>button</Button>);
expect(toJson(button)).toMatchSnapshot();
});
});
执行 npm run test
,没通过,因为跟之前react-test-renderer
渲染的快照不匹配了
我们需要重新写快照,执行npx jest -u
快照更新了,再执行一下npm run test
,通过了
代码中的 toJson 部分可以统一配置到 jest.config.js,添加快照序列化配置,代码里就不用写 toJson 了。
snapshotSerializers: ['enzyme-to-json/serializer']
三、事件测试
利用 mock 函数
测试一下 Button 组件的事件
// components/button/__test__/index.test.js
import React from 'react';
import Button from '../Button';
import { render, mount } from 'enzyme';
describe('Button 组件', () => {
it('正确渲染 Button 组件', () => {
const button = render(<Button>button</Button>);
expect(button).toMatchSnapshot();
});
it('测试 Button 组件 loading 参数', () => {
const fn = jest.fn();
const loadingButton = mount(
<Button loading onClick={fn}>
loading button
</Button>
);
expect(loadingButton).toMatchSnapshot();
loadingButton.find('button').simulate('click');
expect(fn).not.toBeCalled();
});
it('测试 Button 组件 disabled 参数', () => {
const fn = jest.fn();
const disabledButton = mount(
<Button disabled onClick={fn}>
disabled button
</Button>
);
expect(disabledButton).toMatchSnapshot();
disabledButton.find('button').simulate('click');
expect(fn).not.toBeCalled();
});
it('测试 Button 组件 onClick 事件', () => {
const fn = jest.fn();
const button = mount(<Button onClick={fn}>button</Button>);
button.find('button').simulate('click');
expect(fn).toBeCalled();
});
});