本文根据 Devhints / Enzyme 翻译。代码示例及版本范围沿用原文。原文标注更新日期:2020-02-12。
入门
简介
Enzyme 允许你为 React 组件编写单元测试。本指南涵盖 Enzyme 3.x 版本。
- Enzyme 网站 (enzymejs.github.io)
挂载
import {shallow, mount} from 'enzyme'
wrap = shallow(<MyComponent />)
wrap = mount(<MyComponent />)
浅层包装(Shallow wrapping)不会深入到子组件中。完全挂载(Full mount)则会同时挂载子组件。
调试
console.log(wrap.debug())
显示 HTML,用于调试目的。
参见: debug()
示例
基础示例
import { shallow } from 'enzyme'
import MyComponent from '../MyComponent'
it('works', () => {
const wrap = shallow(
<MyComponent name='Groot' />
)
expect(wrap.text()).toEqual('I am Groot')
})
Props(属性)和 state(状态)
设置
wrap.setProps({ name: 'Moe' })
wrap.setState({ show: true })
断言
expect(wrap.prop('name')).toEqual('Moe')
expect(wrap.state('show')).toEqual(true)
expect('name' in wrap.props()).toEqual('Moe')
expect('show' in wrap.state()).toEqual(true)
匹配元素
expect(
wrap.containsMatchingElement(
<span>I am groot</span>
)
).toBeTruthy()
containsMatchingElement() 这可能是 Jest 中最有用的断言。
快照
expect(wrap).toMatchSnapshot()
请确保已为快照配置好 enzyme-to-json(参见 安装 下文)。
遍历
expect(
wrap.find('button').text()
).toEqual('Submit')
使用 .find() 用于向下遍历至节点。它同样会返回包装对象(wrapper objects)。
模拟事件
wrap.find('input').simulate('click')
使用事件对象属性
wrap.find('input').simulate('change', {
target: { value: 'hello' }
})
安装
初始设置
npm install --save-dev enzyme \
enzyme-adapter-react-16 \
react-test-renderer
test/setup.js
import Enzyme from 'enzyme'
import Adapter from 'enzyme-adapter-react-16'
Enzyme.configure({ adapter: new Adapter() })
package.json
"jest": {
"setupFiles": [
"test/setup.js"
]
}
此配置为 React v16 版本设置了 Enzyme,并使用 Jest 自动为您配置 Enzyme。在 Enzyme 的安装说明中,还可以找到其他适配器。
参见: 安装
Jest 快照
npm install --save-dev enzyme-to-json
package.json
"jest": {
"snapshotSerializers": [
"enzyme-to-json/serializer"
]
}
测试
it('works', () => {
wrap = mount(<MyComponent />)
expect(wrap).toMatchSnapshot()
})
可选,但建议使用:这允许您将 Enzyme 包装器(wrappers)与 Jest 快照结合使用。
参见: enzyme-to-json
ReactWrapper
遍历
wrap.find('button') // → ReactWrapper
wrap.filter('button') // → ReactWrapper
wrap.not('span') // → ReactWrapper (inverse of filter())
wrap.children() // → ReactWrapper
wrap.parent() // → ReactWrapper
wrap.closest('div') // → ReactWrapper
wrap.childAt(0) // → ReactWrapper
wrap.at(0) // → ReactWrapper
wrap.first() // → ReactWrapper
wrap.last() // → ReactWrapper
wrap.get(0) // → ReactElement
wrap.getElement() // → ReactElement
wrap.getElements() // → Array<ReactElement>
wrap.getDOMNode() // → DOMComponent
参见: 完整渲染 API
操作
wrap.simulate('click')
React 组件
wrap.setState({ ··· })
wrap.setProps({ ··· })
wrap.setContext({ ··· })
wrap.state() // get full state
wrap.props() // get full props
wrap.context() // get full context
wrap.state('key') // → any
wrap.prop('key') // → any
wrap.context('key') // → any
wrap.instance() // → ReactComponent
挂载(Mount)
wrap.mount()
wrap.unmount()
wrap.update() // calls forceUpdate()
测试
wrap.debug() // → string
wrap.html() // → string
wrap.text() // → string
wrap.type() // → string | function
wrap.name() // → string
wrap.is('.classname') // → boolean
wrap.hasClass('class') // → boolean
wrap.exists() // → boolean
wrap.contains(<div />) // → boolean
wrap.contains([ <div /> ]) // → boolean
wrap.some('.child') // → boolean
wrap.someWhere(n => n.hasClass('foo'))
wrap.containsMatchingElement(<div />) // → boolean
wrap.containsAllMatchingElements([ <div /> ]) // → boolean
wrap.containsAnyMatchingElements([ <div /> ]) // → boolean
参考资料
- Enzyme 网站 (airbnb.io)
- Enzyme v2 速查表 (devhints.io) (旧版本)