最近想给本身的ui轮子写一个单元测试,为何会这么想呢?由于它能涨工资呀,哈哈哈,固然咱们学习是不能那么功利的(放P,哈哈哈)css
除了涨工资没别的了?固然不是,他是有它的好处的,不然学他干吗react
单元测试的好处是啥?git
好了,很少BB,看看怎么用吧!!! github
我用的是jest测试哦!!!web
首先开始看一下我以前的配置,以前的文章有个人配置,避免你找的烦,我把配置放在这里https://github.com/sunkuangdo... 须要的请自行下载吧!json
1.看一下个人jest.config.js中testMatch
,告诉我须要在lib文件夹中建立个目录__tests__
,__tests__
的目录里面xxxx.unit.(js|jsx|ts|tsx)
这样的文件就是测试文件
那就建立个文件夹和文件呗
2.我要测试啥呢?我先测试我ui轮子里面的一个函数,试一下sass
这是我以前写的一个函数,就测试他,他会接受一个className
3.在classes.unit.jsx里面写一个,单元测试babel
// 先将测试文件导入进来 import classes from "../helpers/classes"; // 要在describe里面进行测试 describe('classes', () => { // it是声明,第一个参数是对测试的描述,第二个参数是函数,里面是对测试的执行 it('他接受 className', () => { // 我给classes函数传了一个字符串a const result = classes('a') // 我断言result会是一个字符串a expect(result).toEqual('a') }) })
4.哈哈哈,兴高采烈的运行一下,若是你是yarn而且用的我得配置,就用yarn test
MMP,报错了,说我少了一个配置'babel-preset-react-app',安装一下呗app
yarn add --dev babel-preset-react-app
5.安装成功了,再来一下看看yarn test
,哎,成功,真香!
6.每次改写测试文件,都要我yarn test
,好烦....,试试这个操做yarn test --watch
,每次更改都会自动测试啦!
7.我要是想测试一个icon组件怎么办?来,咱们继续搞起来
看下面这段代码less
import * as renderer from 'react-test-renderer' import React from "react"; import Icon from '../icon' describe("icon",()=>{ it("ICON 是 SVG",()=>{ // 首先用renderer建立一个Icon,而后把Icon转成json const json = renderer.create(<Icon/>).toJSON(); // 这个json进行快照 expect(json).toMatchSnapshot() }) })
8.当我运行到这里觉得能够进行测试的时候,意外出现了....bug了,缘由是我测试的Icon组件中有用到scss没有配置,没法识别
首先在test目录下建立新的目录,并建立下面的两个文件
而后在file-mock.js中加入这段代码module.exports = 'test-file-stub';
在object-mock.js中加入这段代码module.exports = {};
最外层找到jest.config.js文件,替换这段
moduleNameMapper: { "\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/test/__mocks__/file-mock.js", "\\.(css|less|sass|scss)$": "<rootDir>/test/__mocks__/object-mock.js", },
上面这段代码这里来解释一下:
/test/__mocks__/file-mock.js
替换掉/test/__mocks__/object-mock.js
替换掉9.哈哈哈,再跑一下,嗯.....,本觉得解决了,唉!!!新问题出现了,来源于这个文件的报错
嗯?我测试的时候也不须要测试svg啊,果断的删除console.log(error)
,这样子就不报错了
10.咱们来看一下这段代码expect(json).toMatchSnapshot()
,他作了什么样的事情,咱们看一下.snap
<svg className="fui-icon" > <use xlinkHref="#undefined" /> </svg>
他会帮咱们生成一个svg,为何use会是undefined???由于我尚未给他传name值,给name传递一个值,从新运行yarn test以后,报错了
他说咱们修改了内容,可是快照没有修改,与快照不一样,这时候须要从新运行,修改快照里面的内容,从新运行yarn test -u
意味着保存咱们最新的正确的快照
11.咱们来测试一下onClick,首先下载两个库enzyme
和enzyme-adapter-react-16
,运行
yarn add --dev enzyme yarn add --dev enzyme-adapter-react-16
配置test目录下的setupTests.js文件
const enzyme = require('enzyme') const Adapter = require('enzyme-adapter-react-16') enzyme.configure({adapter: new Adapter()})
接下来咱们onClick进行测试,一点一点看他表达了什么意思
咱们是要测试一个点击事件函数,导入了这个库以后,这个库帮咱们生成了一个假的页面,并将测试的函数传入Icon组件,找到svg模拟点击svg,咱们本身建立一个fn测试看看对不对,咱们期待n等于2,若是不肯定是否测试成功,将n改为1试一试
import {mount} from 'enzyme' describe("icon", () => { it("onClick", () => { let n = 1; const fn = () => { n = 2 } // 生成假想页面 const comonent = mount(<Icon name="baidu" onClick={fn}/>) // 找到svg模拟点击svg comonent.find('svg').simulate('click') // 咱们期待n等于2 expect(n).toEqual(2) }) })
可是咱们这个方法有点笨,每次测试都要本身写个fn,傻乎乎的!!!
能不能让jest帮咱们写一个fn呢const fn = jest.fn();
这段代码是让jest建立一个fn()expect(fn).toBeCalled();
咱们期待fn会被调用
it("onClick", () => { const fn = jest.fn(); const component = mount(<Icon name="baidu" onClick={fn}/>) component.find('svg').simulate('click') expect(fn).toBeCalled(); })
运行yarn test,测试经过了,可是咱们不知道是否是真的进行测试了,建立一个fn2,这个fn2咱们并不会传,看看报错了没有,报错了,就是真的测试了,说明onClick被调用了,测试经过了
这即是本人在学习过程当中和你们的分享,一遍遍踩坑,一遍遍爬过来会有许多成长,相信你们也必定有这种感觉,一块儿努力吧!!!