基于 Jest + Enzyme 的 React 单元测试
Posted 博克软件
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了基于 Jest + Enzyme 的 React 单元测试相关的知识,希望对你有一定的参考价值。
现如今,前端开发的框架如雨后春笋般挤入视野,其中,React作为当前技术栈较火的一项技术,优势在于创建交互式UI、快速构建用户界面等等。即使如此,我们还是不能落下单元测试。React的单元测试,就是保证自身代码一个复用性、重构性的良性延展。在比较了众多测试框架之后,我们采用了目前比较流行且优势明显的React单测组合Jest+Enzyme。Jest作为测试框架,它集成了测试执行器、断言库、spy、mock、snapshot和测试覆盖率报告等功能。React项目本身也是使用Jest进行单测的,因此它们俩的契合度相当高。Enzyme作为React单测工具。它扩展了React的TestUtils并通过支持类似jQuery的find语法可以很方便的对render出来的结果做各种断言。
Jest是什么?
Jest 是 Facebook 发布的一个开源的、基于 Jasmine 框架的 javascript 单元测试工具,集成了Mocha,chai,sinon等功能,可以通过npm进行安装和配置,提供了包括内置的测试环境 DOM API支持、断言库、Mock 库等,还包含了Spapshot Testing等特性。
Enzyme是什么?
Enzyme,来自airbnb公司, 是一个用于React的JavaScript测试工具,并通过类似jQuery风格的方式进DOM处理,判断、操纵和历遍 React Components 输出。Enzyme 兼容所有的主要测试运行器和判断库,这对开发者的开发体验还是十分友好的,现阶段中react单元测试主要应用这个来开展。
测试环境怎么搭?
在现有React 应用的基础之上,使用的是Webpack+Babel打包构建应用,首先安装 Jest、Enzyme,以及对应的 babel-jest。
npm install --save-dev jest //安装Jest
npm install --save-dev enzyme enzyme-adapter-react-16 //安装Enzyme
npm install jest enzyme babel-jest --save-dev //安装babel-jest
下载安装完成后,我们需要在react项目package.json文件中配置jest以及jest scripts。这里注意下,一些最最常见配置可能会出错的问题,比如:
moduleFileExtensions:代表支持加载的文件名。
moduleNameMapper:代表需要被 Mock 的资源名称。如果需要 Mock 静态资源(如less、scss等),则需要配置 Mock 的路径 <rootDir>/__mocks__/yourMock.js
transform 用于编译 ES6/ES7 语法,需配合 babel-jest 使用。
下面是基本配置。
//配置Jest
"jest": {
"moduleFileExtensions": [
"js",
"jsx"
],
"moduleNameMapper":{
"\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$":"<rootDir>/__mocks__/fileMock.js",
".*\\.(css|less|scss)$": "<rootDir>/__mocks__/styleMock.js"
},
"transform": {
"^.+\\.js$": "babel-jest"
}
},
//配置Jest scripts
"scripts": {
"dev": "NODE_ENV=development webpack-dev-server --inline --progress --colors --port 3000 --host 0.0.0.0 ",
"test": "jest"
}
来个例子,一个简单应用结构如下:
class App extends Component {
render() {
const { params } = this.props;
return (<section className="todoapp">
<div className="main">
<AddTodoView />
<TodoList filter={params.filter || 'all'} />
</div>
<Footer />
</section>)
}
}
该应用分为三个组件,最外层的 <App />,中间的 Input 输入框 <AddTodoView />,下面的 TODO 列表 <TodoList />。
我们看的出来这里一个UI组件,两个智能组件,我们主要测试智能组件下<AddTodoView /> 和 <TodoList />,是否接受input输入框输入字符之后,创建了Todo,满足了应用的功能。
首先我们引入相关的lib,基本思想就是Enzyme 将React 组件渲染成静态的 html 并分析生成的 HTML 结构。这对简单的单元测试功能已足够。然后模拟 Props,渲染组件创建 Wrapper。我们可以创建一个 setup 函数来实现,这里要用到Jest 提供的 mockFunction函数。
//引入相关lib
import React from ‘react’;
import App from ‘../../src/component/App’;
import {shallow} from ‘enzyme’;
const setup = () => {
// 模拟 props
const props = {
// Jest 提供的mock 函数
onAddClick: jest.fn()
}
// 通过 enzyme 提供的 shallow(浅渲染) 创建组件
const wrapper = shallow(<AddTodoView {...props} />)
return {
props,
wrapper
}
}
接着编写Test Case,完成我们的测试流程,我们要做的测试有两点:
1.组件是否正常渲染。
2.组件是否成功调用props方法。
describe('AddTodoView', () => {
const { wrapper, props } = setup();
// 通过查找存在 Input,测试组件正常渲染
//Case Test 1
it('AddTodoView should be render correctly', () => {
expect(wrapper.find('input').exists());
})
})
//Case Test 2
it('When the key pressed, function onAddClick() shoule be called', () => {
// mock input 输入和 Enter
const mockEvent = {
keyCode: 13,
target: {
value: 'Test'
}
}
//这里的keyup会自动转换成React组件中的onKeyUp调用
wrapper.find('input').simulate('keyup',mockEvent)
// 判断 props.onAddClick 是否被调用
expect(props.onAddClick).toBeCalled();
})
运行 npm run test可以看测试结果,在跑测试脚本中,控制台会有Jest 的错误提示信息,通过错误信息一般都能找到问题的所在。
下面例子是控制台错误提示。
同时 Jest 还能生成测试覆盖率报告的命令,添加上 --coverage 这个参数既可生成。不仅会在控制台显示,还会在项目中生成coverage文件夹,可以直观的看到测试结果。下面例子是来自控制台的测试报告。
下面例子是来自coverage目录下的测试报告。
React单元测试具有非常强的实用性,比如组件UI测试、DOM交互测试、功能函数测试等,通过测试检查功能是否实现,还能提高代码的重构性,一句话,少留坑,造福一下后人。
END
参考资料:
https://segmentfault.com/a/1190000011468620
https://blog.csdn.net/qq_36529459/article/details/82823569
https://www.cnblogs.com/susu8/p/9512393.html
http://react-china.org/t/jest-enzyme-react/11769
如需转载注明出处
以上是关于基于 Jest + Enzyme 的 React 单元测试的主要内容,如果未能解决你的问题,请参考以下文章
使用 Jest / Enzyme 在 React 中的功能组件内部测试方法
应该调用 React Enzyme Jest 错误 jest.fn()
React Redux:使用 Enzyme/Jest 测试 mapStateToProps 和 mapDispatchToProps