一.是什么?
Enzyme是Airbnb开源的React测试工具库,它通过对官方提供的测试工具ReactTestUtils进行二次封装,提供了一套简洁强大的API,类似jQuery的风格,并且内置Cheerio。
二.环境搭建
上篇关于Jest的文章中,我并没有讲环境搭建,因为在我看来,进行类React项目的测试,这两者搭配起来,才是最完美的。所以放在这里讲开发环境的搭建。
安装Jest、Enzyme、babel-jest以及enzyme-adapter-react-16。并进行简单配置。
引入enzyme-adapter-react-16之后,我们在每一个测试文件中,都要执行以下操作。
import Enzyme from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
Enzyme.configure({ adapter: new Adapter() });
为了解这个问题,可以将上面的代码存储为一个单独的文件,在jest的配置项setupFilesAfterEnv中,引入这个文件,以后在每次测试前,都会先运行这个文件中的代码,进行环境的初始化。
这里,贴一个基于TypeScript + React-Native的项目环境配置。
"jest": {
"preset": "react-native",
"moduleFileExtensions": [
"ts",
"tsx",
"js"
],
"snapshotSerializers": [
"enzyme-to-json/serializer"
],
// 测试前的环境准备,这里的setup.js就是我们上面说的那段代码。
"setupFilesAfterEnv": [
"jest-enzyme",
"<rootDir>/__tests__/testUtils/setup.js"
],
"testEnvironment": "enzyme",
// 待测试代码
"testMatch": [
"<rootDir>/__tests__/src/**/*.{spec,test}.{js,jsx,ts,tsx}"
],
// 测试时要忽略的代码
"testPathIgnorePatterns": [
"\\.snap$",
"<rootDir>/node_modules/"
],
// 转换器,由于测试代码中会使用ES6,或者更新的ES代码,所以需要转译。
"transform": {
"^.+\\.([jt]sx?)$": "<rootDir>/node_modules/babel-jest",
"^.+\\.(ts|tsx)?$": "ts-jest"
},
// 转译时需要忽略的代码,?!这种形式表示除了这些代码之外的代码都忽略,这里意味着需要转译node_modules下的react-native中的代码,这是因为react-native中某些包在发布时,是以源码进行发布的,所以,我们需要手动转译。楼主曾经在这翻了大跟斗!
"transformIgnorePatterns": [
"<rootDir>/node_modules/(?!(react-native|react-native-deprecated-custom-components)/)"
],
"collectCoverageFrom": [
"src/**/*.ts",
"!**/node_modules/**",
"!src/**/model.ts"
],
"coverageReporters": [
"text-summary",
"json-summary",
"lcov",
"html"
]
}
三.3种渲染模式
- render:静态渲染,它将React组件渲染成静态的HTML字符串,然后使用Cheerio这个库解析这段字符串,并返回一个Cheerio的实例对象,可以用来分析组件的html结构。对于snapshot使用render比较合适。
- shadow:浅渲染,是对官方的Shallow Renderer的封装。将组件渲染成虚拟DOM对象,只会渲染第一层,子组件将不会被渲染出来,使得效率非常高。
- mount:完全渲染,它将组件渲染加载成一个真实的DOM节点,用来测试DOM API的交互和组件的生命周期。用到了jsdom来模拟浏览器环境
shallow和mount对组件的渲染结果不是html的dom树,而是react树。并且shallow和mount返回的结果是个被封装的ReactWrapper,可以进行多种操作,比如:find()、children()等选择器进行元素查找,state()、props()进行数据查找,setState()、setprops()操作数据;simulate()模拟事件触发。
四.常用方法
- simulate(event, mock):模拟事件,用来触发事件,event为事件名称,mock为一个event object。
- instance():返回组件的实例。
- find(selector):根据选择器查找节点,selector可以是CSS中的选择器,或者是组件的构造函数,组件的display name等。
- text():返回当前组件的文本内容。
- html(): 返回当前组件的HTML代码形式。
- props():返回根组件的所有属性。
- prop(key):返回根组件的指定属性。
- state():返回根组件的状态。
- setState(nextState):设置根组件的状态。
- setProps(nextProps):设置根组件的属性。