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

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

使用 enzyme+jest 可以很方便的来测试我们的 react 应用

测试需要关注哪些方面

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

安装依赖

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

设置启动文件

按照 enzyme 文档,测试前是需要做一些准备工作的, 所以我们在根目录下添加test.setup.ts

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

configure({ adapter: new Adapter() })

同时修改jest.config.js文件

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

模拟浏览器环境

react 应用运行的时候是在浏览器环境,但是我们测试的时候是在 node 环境,所以需要我们模拟出浏览器环境才能正确的运行测试。之前的做法是在无头浏览器中跑测试代码,但现在我们有一个更好的、更轻量的方法,就是使用jsdom

安装 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.ts

/**
 * 返回按钮
 */
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! 是不是很简单。

测试 connected 组件

测试 connected 组件有两种方法。

  • 一种是使用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! 是不是也很简单。

其他例子

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

测试覆盖率

测试覆盖率是评价测试一个很重要的指标,我们可以通过yarn jest --coverage生成测试报告,查看代码中没有被测试到的分支,一点点的提高测试覆盖率

最后

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

    原文作者:xiguadada
    原文地址: https://segmentfault.com/a/1190000017124978
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞