What
采用 Jest 对 react 项目进行单元测试。
Why
曾使用 Mocha 对项目进行过单元测试,但是 Mocha 需要配合一系列工具包( sinon, enzyme, chai, nyc )等,加上 Mocha 对 typescript 支持不是特别友好。所以打算采用 Jest 进行单元测试,目前的测试工具 Mocha、Jest、Ava 区别大致如下:
框架 | 断言 | 异步 | Mock | 代码覆盖率 |
---|---|---|---|---|
Mocha | 不支持(Chai/power-asset) | 友好 | 不支持(Sinon) | 不支持(Istanbul) |
Jest | 默认支持 | 友好 | 默认支持 | 支持 |
Ava | 默认支持 | 友好 | 不支持(Sinon) | 不支持(Istanbul) |
How
配置包与命令
安装所需依赖(采用的 typescript )
yarn add -D jest babel-jest jest-transform-stub ts-jest enzyme-to-json enzyme enzyme-adapter-react-16
配置命令
...
"scripts": {
"test": "cross-env jest",
"test:with-coverage": "cross-env TEST_COVERAGE=true jest"
},
...
配置 Jest
根目录下编辑 jest.config.js
module.exports = {
preset: "ts-jest", // 采用 ts 测试
setupFiles: ["./jest.setup.js"],
transform: {
"^.+\\.[tj]s?$": "babel-jest",
"^.+\\.[tj]sx?$": "babel-jest",
"^.+\\.(css|styl|less|sass|scss|png|jpg|ttf|woff|woff2|svg)$":
"jest-transform-stub",
},
moduleNameMapper: {
"^@/(.*)$": "<rootDir>/src/$1", // 用 @ 映射当前 src 下的路径
"^.+.(css|styl|less|sass|scss|png|jpg|ttf|woff|woff2|svg)$":
"jest-transform-stub", // stub 掉 css|styl|less|sass|scss|png|jpg|ttf|woff|woff2|svg 的测试
"\\.worker.entry.js": "<rootDir>/__mocks__/workerMock.js",
},
globals: {
"ts-jest": {
tsConfig: "./tsconfig.test.json", // 指定 ts 测试配置文件
},
},
collectCoverage: process.env.TEST_COVERAGE ? true : false, // 是否需要查看测试覆盖率
collectCoverageFrom: ["<rootDir>/src/**/*.{ts,tsx}", "!**/node_modules/**"],
testPathIgnorePatterns: ["<rootDir>/dist/", "<rootDir>/node_modules/"],
snapshotSerializers: ["enzyme-to-json/serializer"],
transformIgnorePatterns: ["<rootDir>/dist/", "<rootDir>/node_modules/"],
testURL: "http://localhost",
clearMocks: true,
};
根目录下编辑 jest.setup.js
// 该文件是运行单元测试前会执行一遍,可以 mock 掉一些报错的东西
const React = require("react");
if (typeof window !== "undefined") {
global.window.resizeTo = (width, height) => {
global.window.innerWidth = width || global.window.innerWidth;
global.window.innerHeight = height || global.window.innerHeight;
global.window.dispatchEvent(new Event("resize"));
};
global.window.scrollTo = () => {};
if (!window.matchMedia) {
Object.defineProperty(global.window, "matchMedia", {
value: jest.fn((query) => ({
matches: query.includes("max-width"),
addListener: jest.fn(),
removeListener: jest.fn(),
})),
});
}
const mockResponse = jest.fn();
Object.defineProperty(window, "location", {
value: {
hash: {
endsWith: mockResponse,
includes: mockResponse,
},
assign: mockResponse,
},
writable: true,
});
}
const Enzyme = require("enzyme");
const Adapter = require("enzyme-adapter-react-16");
Enzyme.configure({ adapter: new Adapter() });
Object.assign(Enzyme.ReactWrapper.prototype, {
findObserver() {
return this.find("ResizeObserver");
},
triggerResize() {
const ob = this.findObserver();
ob.instance().onResize([{ target: ob.getDOMNode() }]);
},
});
console.log("Current React Version:", React.version);
至此 Jest 项目搭建就已经完成了, 比 Mocha 简单些。
Jest 使用
编写测试文件
import React from "react";
import { App as TargetComponent } from "../App";
import { shallow } from "enzyme";
describe("src > APP", () => {
const defaultProps = {
updateTabs: jest.fn(), // 模拟 updateTabs 函数
user: {},
};
// shallow 浅拷贝模拟 react 组件
const render = (props: {} = {}) =>
shallow(<TargetComponent {...defaultProps} {...props} />);
// describe 一个方法
describe("componentDidMount", () => {
// 判断行为
it("should direct return if no tab", () => {
// 实例化组件
const component = render({
user: {
permissionsMapping: {
"/": null,
},
},
});
// 执行方法
const result = component.instance().componentDidMount();
// 执行断言
expect(component.instance().props.updateTabs).toBeCalledWith("test");
expect(result).toBeUndefined();
});
});
});
执行单元测试
yarn test
或者执行单个测试文件
# 采用 describe.only 方法不行,略坑
node_modules/.bin/jest src/components/BaseList/__test__/index.test.tsx
查看覆盖率
yarn test:with-coverage
在跟目录下 coverage 下会生成 html 文件,在浏览器打开查看覆盖率即可,可以在 Jest 配置中配置测试率要求,具体可以查看官网文档。
总结
个人感觉 Jest 比 Mocha 配置简单些,易上手,Mocha 需要配合 sinon 进行 stub,配合 Chai 断言效果才会更好,在使用上 Jest 和 Mocha 并无太大区别。
(完)
作者: Kavience
本文链接: http://www.kavience.com/frontend/jest-unit-testing.html
转载请注明:《Jest单元测试》转自 http://www.kavience.com/frontend/jest-unit-testing.html,原作者:Kavience
版权声明: 自由转载-非商用-非衍生-保持署名(创意共享3.0许可证)