Enzyme是一个用于React的JavaScript测试实用程序,它使得更容易断言,操作和遍历您的React组件的输出,它模拟了jQuery的API,非常直观,易于使用和学习。
整理相当API为中文,所以资料都是官方API翻译而已,代码块以最新的粘贴过来
它提供三种测试方法:
- shallow
- render
- mount
先解释一个词:wrapper
wrapper是enzyme包装好的类,以供api使用
shallow方法
shallow
在单元测试的过程中,浅渲染
将一个组件渲染成虚拟DOM对象,并不会渲染其内部的子组件,也不是真正完整的React Render
,无法与子组件互动。
以下shallow浅层渲染代码案例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
|
import React from 'react';
import { expect } from 'chai';
import { shallow } from 'enzyme';
import sinon from 'sinon';
import MyComponent from './MyComponent';
import Foo from './Foo';
describe('<MyComponent />', () => {
it('renders three <Foo /> components', () => {
const wrapper = shallow(<MyComponent />);
expect(wrapper.find(Foo)).to.have.lengthOf(3);
});
it('renders an `.icon-star`', () => {
const wrapper = shallow(<MyComponent />);
expect(wrapper.find('.icon-star')).to.have.lengthOf(1);
});
it('renders children when passed in', () => {
const wrapper = shallow((
<MyComponent>
<div className="unique" />
</MyComponent>
));
expect(wrapper.contains(<div className="unique" />)).to.equal(true);
});
it('simulates click events', () => {
const onButtonClick = sinon.spy();
const wrapper = shallow(<Foo onButtonClick={onButtonClick} />);
wrapper.find('button').simulate('click');
expect(onButtonClick).to.have.property('callCount', 1);
});
});
|
render方法介绍
render静态渲染API,使用enzyme's 的render
函数从React树生成HTML,并分析生成的HTML结构。render
返回包装非常类似于在enzyme's的其它渲染器,render
使用第三方HTML解析和遍历库 Cheerio。我们相信Cheerio非常好地处理HTML的解析和遍历,并且自己复制这个功能
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
import React from 'react';
import { expect } from 'chai';
import { render } from 'enzyme';
import Foo from './Foo';
describe('<Foo />', () => {
it('renders three `.foo-bar`s', () => {
const wrapper = render(<Foo />);
expect(wrapper.find('.foo-bar')).to.have.lengthOf(3);
});
it('renders the title', () => {
const wrapper = render(<Foo title="unique" />);
expect(wrapper.text()).to.contain('unique');
});
});
|
mount方法介绍
mount完整的DOM渲染非常适用于组件可能与DOM API交互或需要测试包含在更高阶组件中的组件的情况。
完整DOM渲染要求在全局范围内提供完整的DOM API。这意味着它必须在至少“看起来像”浏览器环境的环境中运行。如果您不想在浏览器中运行测试,推荐的使用方法mount
是依赖于一个名为jsdom的库,它本质上是一个完全用JS实现的无头浏览器。
注意:与浅层或静态渲染不同,完全渲染实际上将组件安装在DOM中,这意味着如果测试全部使用相同的DOM,则测试可以相互影响。在编写测试时请记住这一点,并在必要时使用.unmount()
或类似清理。
以下render完整的DOM渲染案例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
import React from 'react';
import sinon from 'sinon';
import { expect } from 'chai';
import { mount } from 'enzyme';
import Foo from './Foo';
describe('<Foo />', () => {
it('allows us to set props', () => {
const wrapper = mount(<Foo bar="baz" />);
expect(wrapper.props().bar).to.equal('baz');
wrapper.setProps({ bar: 'foo' });
expect(wrapper.props().bar).to.equal('foo');
});
it('simulates click events', () => {
const onButtonClick = sinon.spy();
const wrapper = mount((
<Foo onButtonClick={onButtonClick} />
));
wrapper.find('button').simulate('click');
expect(onButtonClick).to.have.property('callCount', 1);
});
it('calls componentDidMount', () => {
sinon.spy(Foo.prototype, 'componentDidMount');
const wrapper = mount(<Foo />);
expect(Foo.prototype.componentDidMount).to.have.property('callCount', 1);
Foo.prototype.componentDidMount.restore();
});
});
|
shallow(node[, options]) => ShallowWrapper
参数
- node (ReactElement): 要渲染的组件
- options (Object [optional]):
- options.context: (Object [optional]): 要传递到组件的上下文
返回
ShallowWrapper: 在渲染输出后,返回浅渲染ShallowWrapper实例
ShallowWrapper API
.at(index) => ShallowWrapper
返回当前索引的的节点到 wrapper 在当前包装器的给定索引处返回节点周围的包装器。
参数
- index (Number): 从0开始的整数,来选择取回的第几个节点
返回
ShallowWrapper
例子
1
2
|
const wrapper = shallow(<MyComponent />);
expect(wrapper.find(Foo).at(0).props().foo).to.equal("bar");
|
类似方法 .get(index) => ReactElement
.childAt(index) => ShallowWrapper
返回具有指定索引的子元素到新的wrapper
.find(selector) => ShallowWrapper
根据选择器,找到渲染树中的节点。
.findWhere(predicate) => ShallowWrapper
找到渲染树中里被的断言函数返回true的节点 参数:predicate (ShallowWrapper => Boolean) 断言函数返回布尔值
.filter(selector) => ShallowWrapper
过滤当前包装器中与所提供的选择器不匹配的节点。
.filterWhere(predicate) => ShallowWrapper
过滤当前包装器里被断言函数predicate不返回true的节点
.contains(nodeOrNodes) => Boolean
返回给定的 节点/节点数组 是否在渲染树中的布尔值。
.containsMatchingElement(node) => Boolean
返回在浅渲染树中是否存在给定的node节点 的布尔值。
.containsAllMatchingElements(nodes) => Boolean
返回在浅渲染树中是否存在给定的 所有 react元素 的布尔值。
.containsAnyMatchingElements(nodes) => Boolean
返回在浅渲染树中是否存在给定react元素 之一 的布尔值
.equals(node) => Boolean
根据期望值,返回当前渲染树是否等于给定节点的 布尔值
.matchesElement(node) => Boolean
返回当前给定的react元素 是否 匹配浅渲染树 的布尔值
.hasClass(className) => Boolean
是否有这个className
.is(selector) => Boolean
当前节点是否与提供的选择器匹配
.exists() => Boolean
当前节点是否存在
.isEmpty() => Boolean
弃用: 用 .exists() 代替.
.not(selector) => ShallowWrapper
删除当前wrapper中与所提供的选择器匹配的节点。 (与 .filter()作用相反)
.children() => ShallowWrapper
获取当前 wrapper 中所有子节点的 wrapper.
.childAt(index) => ShallowWrapper
返回具有指定索引的子元素的 wrapper
.parents() => ShallowWrapper
获取当前节点的所有父级(祖先)
.parent() => ShallowWrapper
获取当前节点的直接父级
.closest(selector) => ShallowWrapper
根据选择器,获取当前节点的第一个祖先
Get a wrapper with the first ancestor of the current node to match the provided selector.
.shallow([options]) => ShallowWrapper
Shallow renders the current node and returns a shallow wrapper around it.
.render() => CheerioWrapper
返回当前节点的子树的CheerioWrapper
.unmount() => ShallowWrapper
卸载组件的方法
.text() => String
返回当前渲染树中文本节点的 字符串表示形式。
.html() => String
返回当前节点的静态HTML呈现
.get(index) => ReactElement
返回给出索引的节点 ReactElement
.getNode() => ReactElement
返回底层节点
.getNodes() => Array<ReactElement>
返回底层的一些节点
.at(index) => ShallowWrapper
返回 参数:索引节点的 浅wrapper。
.first() => ShallowWrapper
返回当前第一个节点 wrapper
.last() => ShallowWrapper
返回当前最后一个节点 wrapper
.state([key]) => Any
返回根组件的状态
.context([key]) => Any
返回根组件的上下文环境
.props() => Object
返回当前节点的 props
.prop(key) => Any
返回当前节点props的某个(key)属性的值
.key() => String
返回当前节点的键(key)
.simulate(event[, data]) => ShallowWrapper
模拟当前节点上的事件
.setState(nextState) => ShallowWrapper
手动setState更新根组件状态
.setProps(nextProps) => ShallowWrapper
手动更新根组件的props
.setContext(context) => ShallowWrapper
手动设置根组件的上下文
.instance() => ReactComponent
返回根组件的实例
.update() => ShallowWrapper
在根组件实例上调用.forceUpdate()
.debug() => String
返回当前浅渲染树的字符串表示形式,以便进行调试
.type() => String|Function
返回包装器(wapper)的当前节点的类型。
.name() => String
返回当前节点的名称
.forEach(fn) => ShallowWrapper
迭代当前的每个节点并执行提供的函数
.map(fn) => Array
将当前的节点数组映射到另一个数组
.reduce(fn[, initialValue]) => Any
将当前节点数组减少为一个值
.reduceRight(fn[, initialValue]) => Any
将当前节点数组从右到左减少为一个值 Reduces the current array of nodes to a value, from right to left.
.slice([begin[, end]]) => ShallowWrapper
根据Array#slice的规则返回具有原始包装器的节点的子集的新包装器。
.tap(intercepter) => Self
点击wrapper方法链。有助于调试。 Taps into the wrapper method chain. Helpful for debugging.
.some(selector) => Boolean
返回 是否有 节点与提供的选择器匹配。
.someWhere(predicate) => Boolean
返回 是否有 节点 传递所提供的断言函数。
.every(selector) => Boolean
返回 是否 有节点与提供的选择器匹配。
.everyWhere(predicate) => Boolean
返回 是否 所有 节点都传递所提供的断言函数。
.dive([options]) => ShallowWrapper
浅渲染当前wrapper的一个非DOM子元素,并在结果周围返回一个wrapper
exspect(运行结果).toBe(期望的结果); //常见断言方法 expect({a:1}).toBe({a:1})//判断两个对象是否相等 expect(1).not.toBe(2)//判断不等 expect({ a: 1, foo: { b: 2 } }).toEqual({ a: 1, foo: { b: 2 } }) expect(n).toBeNull(); //判断是否为null expect(n).toBeUndefined(); //判断是否为undefined expect(n).toBeDefined(); //判断结果与toBeUndefined相反 expect(n).toBeTruthy(); //判断结果为true expect(n).toBeFalsy(); //判断结果为false expect(value).toBeGreaterThan(3); //大于3 expect(value).toBeGreaterThanOrEqual(3.5); //大于等于3.5 expect(value).toBeLessThan(5); //小于5 expect(value).toBeLessThanOrEqual(4.5); //小于等于4.5 expect(value).toBeCloseTo(0.3); // 浮点数判断相等 expect('Christoph').toMatch(/stop/); //正则表达式判断 expect(['one','two']).toContain('one'); //不解释
https://blog.csdn.net/F_Felix/article/details/118275875