使用 enzyme+jest 能夠很方便的來測試咱們的 react 應用javascript
yarn add -D enzyme enzyme-adapter-react-16 @types/enzyme @types/enzyme-adapter-react-16
按照 enzyme 文檔,測試前是須要作一些準備工做的, 因此咱們在根目錄下添加test.setup.ts
html
// 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 環境,因此須要咱們模擬出瀏覽器環境才能正確的運行測試。以前的作法是在無頭瀏覽器中跑測試代碼,但如今咱們有一個更好的、更輕量的方法,就是使用jsdom
。node
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
react
/** * 返回按鈕 */ 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 組件有兩種方法。redux
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
可能大部分項目礙於各類狀況,時間不夠,需求變化太快等等,放棄編寫測試,所有交給測試人員去測。可是,寫不寫測試是一回事,會不會寫測試是另外一會事。但願各位在這又收穫了一點小知識。:)