以 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();
});
});