基于 Jest + Enzyme 的 React 单元测试
前言如果你想学习 React 单元测试,那就从这篇文章开始吧。Star 项目,clone 到本地,根据教程走一遍,有任何问题欢迎 issue 讨论。
文章主要内容如下:
Jest、Enzyme 介绍Jest 是 Facebook 发布的一个开源的、基于 Airbnb开源的 React 测试类库 Enzyme 提供了一套简洁强大的 API,并通过 jQuery 风格的方式进行DOM 处理,开发体验十分友好。不仅在开源社区有超高人气,同时也获得了React 官方的推荐。 测试环境搭建在开发 React 应用的基础上(默认你用的是 Webpack + Babel 来打包构建应用),你需要安装 npm install jest enzyme babel-jest --save-dev 下载 npm 依赖包之后,你需要在 "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" } }, 并新增 "scripts": { "dev": "NODE_ENV=development webpack-dev-server --inline --progress --colors --port 3000 --host 0.0.0.0 ","test": "jest" } 其中 :
上面三个是常用的配置,更多 Jest 配置见官方文档:Jest Configuration 测试脚本编写UI 组件测试环境搭建好了,就可以开始动手写测试脚本了。在开始之前,先分析下 Todo 应用的组成部分。
应用主体结构如下 class App extends Component { render() { const { params } = this.props; return ( <section className="todoapp"> <div className="main"> <AddTodo /> <VisibleTodoList filter={params.filter || 'all'} /> </div> <Footer /> </section> ) } } 可以发现 整个应用可以分为三个组件:
其中
import React,{ Component,PropTypes } from 'react' class AddTodoView extends Component { render() { return ( <header className="header"> <h1>todos</h1> <input className="new-todo" type="text" onKeyUp={e => this.handleClick(e)} placeholder="input todo item" ref='input' /> </header> ) } handleClick(e) { if (e.keyCode === 13) { const node = this.refs.input; const text = node.value.trim(); text && this.props.onAddClick(text); node.value = ''; } } } 了解了该组件的功能之后,我们首先需要明确该组件需要测试哪些点:
经过上面的分析之后,我们就可以开始编写单元测试脚本了。 第一步:引入相关 libimport React from 'react' import App from '../../src/component/App' import { shallow } from 'enzyme' 在这里我们引入了
一般情况下, 第二步:模拟 Props,渲染组件创建 Wrapper这一步,我们可以创建一个 const setup = () => { // 模拟 props const props = { // Jest 提供的mock 函数 onAddClick: jest.fn() } // 通过 enzyme 提供的 shallow(浅渲染) 创建组件 const wrapper = shallow(<AddTodoView {...props} />) return { props,wrapper } }
第四步:编写 Test Case这里的 Case 根据我们前面分析需要测试的点编写。 Case1:测试组件是否正常渲染 describe('AddTodoView',() => { const { wrapper,props } = setup(); // case1 // 通过查找存在 Input,测试组件正常渲染 it('AddTodoView Component should be render',() => { //.find(selector) 是 Enzyme shallow Rendering 提供的语法,用于查找节点 // 详细用法见 Enzyme 文档 http://airbnb.io/enzyme/docs/api/shallow.html expect(wrapper.find('input').exists()); }) }) 写完第一个测试用例之后,我们可以运行看看测试的效果。在 Terminal 中输入
Case2: 输入内容并敲下回车键,测试组件调用props的方法 it('When the Enter key was pressed,onAddClick() shoule be called',() => { // mock input 输入和 Enter事件 const mockEvent = { keyCode: 13,// enter 事件 target: { value: 'Test' } } // 通过 Enzyme 提供的 simulate api 模拟 DOM 事件 wrapper.find('input').simulate('keyup',mockEvent) // 判断 props.onAddClick 是否被调用 expect(props.onAddClick).toBeCalled() }) 上面的代码与第一个 case 多了两点:
我们再运行
经过上面两个 Test Case 的分析,接下来的 Case3 和 Case4 思路也是一样,具体写法见代码: __test__/component/AddTodoView.spec.js,这里就不一一讲解了。 Reducer 测试由于 Reducer 是纯函数,因此对 Reducer 的测试非常简单,Redux 官方文档也提供了测试的例子,代码如下: import * as actions from '../../src/actions/index' import * as types from '../../src/constants/actionTypes' describe('actions',() => { it('should create an action to add a todo',() => { const text = 'Finish docs' const expectedAction = { type: types.ADD_TODO,text } expect(actions.addTodo(text)).toEqual(expectedAction) }) }) 调试及测试覆盖率报告在运行测试脚本过程,
而且还会在项目中生成 资料
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |