使用 Enzyme 测试 react-redux-app(接上一篇)

使用 Enzyme 测试 react-redux-app(接上一篇)

使用 enzyme+jest 能够很方便的来测试咱们的 react 应用javascript

测试须要关注哪些方面

  • 页面的结构的测试(通常是去 判断 dom 结构对不对)
  • 样式的测试(这个比较复杂,可能须要咱们去截图对比,简单点的作法,就直接对比样式代码是否有变动,这个只对 inline-style 有效)
  • 交互的测试( 测试一些交互可否正常被触发)

安装依赖

yarn add -D enzyme enzyme-adapter-react-16 @types/enzyme @types/enzyme-adapter-react-16

设置启动文件

按照 enzyme 文档,测试前是须要作一些准备工做的, 因此咱们在根目录下添加test.setup.tshtml

// test.setup.ts
import { configure } from 'enzyme'
import * as Adapter from 'enzyme-adapter-react-16'

configure({ adapter: new Adapter() })

同时修改jest.config.js文件java

module.exports = {
  preset: 'ts-jest',
  testEnvironment: 'node',
  setupTestFrameworkScriptFile: '<rootDir>/test.setup.ts'
}

模拟浏览器环境

react 应用运行的时候是在浏览器环境,可是咱们测试的时候是在 node 环境,因此须要咱们模拟出浏览器环境才能正确的运行测试。以前的作法是在无头浏览器中跑测试代码,但如今咱们有一个更好的、更轻量的方法,就是使用jsdomnode

安装 jsdom

yarn add -D jsdom @types/jsdom

# 顺带安装一下requestAnimation的模拟,react须要
yarn add -D raf

修改test.setup.ts

import 'raf/polyfill'
import { configure } from 'enzyme'
import * as Adapter from 'enzyme-adapter-react-16'
import * as jsdom from 'jsdom'

const { window } = new jsdom.JSDOM('<!doctype html><html><body></body></html>')

global.window = window
global.document = window.document

configure({ adapter: new Adapter() })

编写测试

测试简单的组件

咱们先写一个测试文件测一个简单的组件test/BtnBack.test.tsreact

/**
 * 返回按钮
 */
import * as React from 'react'
import { Button } from 'antd'
import { ButtonProps } from 'antd/lib/button'
import { win } from '../../util'

const BtnBack: React.SFC<ButtonProps> = props => (
  <Button onClick={win.goBack} {...props}>
    返回
  </Button>
)

export default BtnBack
import * as React from 'react'
import { shallow } from 'enzyme'
import BtnBack from '../../src/components/BtnBack'
import { Button } from 'antd'

test('<BtnBack />', () => {
  const wrapper = shallow(<BtnBack />)

  // 这部分是 结构测试
  const props = wrapper.find(Button).props()

  expect(props.children).toEqual('返回')

  // 这部分是 交互测试
  global.window = {
    history: {
      back: jest.fn()
    }
  }

  wrapper.find(Button).simulate('click')

  expect(global.window.history.back).toBeCalled()
})

done! 是否是很简单。shell

测试 connected 组件

测试 connected 组件有两种方法。redux

  • 一种是使用dive方法,dive 能剥离 第一层组件,返回 connected 组件里第一个非 dom 的 child-node,也就是咱们本身写的组件,而后就像测一个简单组件同样去测 这个组件。固然,测试的时候须要模拟出 connected 产生的一些 props。
  • 另外一种就是模拟出 redux-store,我用的是这种

安装 mock-store

yarn add -D redux-mock-store @types/redux-mock-store

编写测试

import * as React from 'react'
import Selector from '../../src/components/Selector'
import configureStore from 'redux-mock-store'
import { mount } from 'enzyme'
import { Select } from 'antd'

const middlewares = []
const mockStore = configureStore(middlewares)

const initState = {
  dataList: [
    {
      value: 1,
      desc: '1'
    },
    {
      value: 2,
      desc: '2'
    }
  ]
}

const store = mockStore(initState)

test('loadActin: Function, dataSouce: any', () => {
  let count = 0

  const loadAction = () => {
    count++
    return {
      type: 'TEST'
    }
  }

  const wrapper = mount(
    <Selector
      loadAction={loadAction}
      statePicker={state => state.dataList}
      store={store}
    >
      {(dataSource, Option) => {
        return dataSource.map((e: any, i: number) => (
          <Option key={i} value={e.value}>
            {e.desc}
          </Option>
        ))
      }}
    </Selector>
  )

  // action 被调用
  expect(count).toBe(1)

  // 渲染出正确的option 数量
  const opts = wrapper.find(Select).prop('children') as any[]
  expect(opts.length).toBe(2)
}

done! 是否是也很简单。api

其余例子

大部分测试状况,都能在 enzyme 的文档中找到例子,我这边只是简单的介绍一下,enzyme 如何使用。浏览器

测试覆盖率

测试覆盖率是评价测试一个很重要的指标,咱们能够经过yarn jest --coverage生成测试报告,查看代码中没有被测试到的分支,一点点的提升测试覆盖率antd

最后

可能大部分项目碍于各类状况,时间不够,需求变化太快等等,放弃编写测试,所有交给测试人员去测。可是,写不写测试是一回事,会不会写测试是另外一会事。但愿各位在这又收获了一点小知识。:)

相关文章
相关标签/搜索