Test Utilities
安装
- 引入
Test Utilites
import ReactTestUtils from "react-dom/test-utils"; // ES6
var ReactTestUtils = require('react-dom/test-utils'); // ES5 with npm
enzyme
① shallow:是官方测试工具库 react-addons-test-utils 中 shallow rendering 的封装。是将一个组件渲染成虚拟DOM对象的“浅渲染”。这种渲染不会涉及子组件,不需要DOM,生成的是虚拟DOM,所以渲染最快,然而它并不能测试子组件的相关代码。
② mount:用于将React组件加载为真实DOM节点,它会生成完整的DOM节点,所以可以测试子组件。但是要依赖一个用jsdom模拟的浏览器环境。
③ render:会根据react组件得到一个静态HTML文本结果,借助一个第三方的HTML解析库Cheerio去生成一个类似于mount和shallow得到的封装对象。它会将react组件渲染为html文本,然后在内部通过Cheerio自动生成一个Cheerio对象。
shallow是最快,但是shallow有局限性,render的效率是mount的两倍。shallow和mount因为都是dom对象的缘故,所以都是可以模拟交互的,而render是不能的。
Selector
1.CSS Selector
- class syntax (
.foo
,.foo-bar
, etc. ) - element tag name syntax (
input
,div
,span
, etc. ) - id syntax (
#foo
,#foo-bar
, etc. ) - attrbute syntax (
[href]="foo"
,[type="text"]
, etc. ) - universal syntax (
*
)
The key
and ref
props will never work
2.A React Component Constructor
This kind of selector only checks the component type,it ignores props and children.
function MyComponent() {
return <div />
}
// find instances of MyComponent
const myComponent = wrapper.find(MyComponent)
3.A React Component’s displayName
The selector is a string starting with a capital letter.String starting with lower case letters will be assumed to be a CSS selector (therefore a tag name).
function MyComponent() {
return <div />
}
MyComponent.displayName = "My Component";
// find instances of MyComponent
const myComponent = wrapper.find("My Component");
ShallowWrapper API
.find(selector) => ShallowWrapper
Find every node in the render tree that matches the provided selector
import React from "react";
import { expect, assert } from "chai";
import { shallow } from "enzyme";
// 配置 enzyme
import { configure } from "enzyme";
import Adapter from "enzyme-adapter-react-16";
configure({ adapter: new Adapter() });
// 引入 component
import Counter2 from "../src/components/counter2component";
describe('测试 counter2Component 文件', function () {
// 浅渲染 Counter2
const wrapper = shallow(<Counter2 />)
// 查找 a 便签的属性 href 是否为 #
it('a 标签的属性 href 为 #', function () {
expect(
wrapper.find('a').prop('href')
).to.equal('#')
})
// 通过属性 [type="text"] 查找
it('[type="text"] is existing',() => {
expect(
wrapper.find('[type="text"]').length
).to.equal(1)
})
// 测试是否含有两个 button 标签
it('Counter2 includes two button elements',() => {
expect(
wrapper.find('button')
).to.have.lengthOf(2)
})
// 通过 className 查找标签
it('it includes an element which className is addBtn',() => {
expect(
wrapper.find('.addBtn')
).to.have.lengthOf(1)
})
})
.findWhere(fn) => ShallowWrapper(n)
Finds every node in the render tree that returns true for the provided predicate function.
.filter(selector) => ShallowWrapper(n)
Returns a new wrapper with only the nodes of the current wrapper that match the provided selector.
.filterWhere(fn) => ShallowWrapper(n)
Returns a new wrapper with only the nodes of the current wrapper that, when passed into the provided predicate function, return true.
.hostNodes => ShallowWrapper
查找主节点时,默认查找的是 HTML 标签而不是 React components;
/* Counter2component.js */
class Counter2 extends React.Component{
render(){
return(
<div>
<Box className="foo" />
<span className="foo"></span>
<span className="foo"></span>
<span className="foo"></span>
</div>
)
}
}
/* test/components.test.js */
describe('测试 Counter2Component 文件',() => {
it('主节点是 HTML 而不是 React 组件', () => {
const wrapper = shallow(<Counter2 />)
const twoNodes = wrapper.find(".foo");
expect(
twoNodes.hostNodes()
).to.have.lengthOf(3)
})
})
.contains( nodeOrNods ) => Boolean
Returns whether or not all given react elements match elements in the render tree. It will determine if an element in the wrapper matches the expected element by checking if the expected element has the same props as the wrapper’s element and share the same values.
/* Counter2component.js */
class Counter2 extends React.Component{
render(){
const num = 4;
return(
<div>
<div data-id="id" data-name="name" className="container">id</div>
</div>
<div data-num="num">
{num}
</div>
)
}
}
/* test/components.test.js */
describe('测试 counter2Component 文件', function () {
const wrapper = shallow(<Counter2 />)
it('测试是否包含完整自定义属性便签',() => {
expect(
wrapper.contains(
<div data-id="id" data-name="name"className="container">id</div>) // 必须完整的书写,有一点不同,都无法通过
).to.equal(true)
})
const num = 4;
expect(
wrapper.contains(<div data-num="num">{num}</div>)
).to.equal(true);
})
-
contains()期望使用一个ReactElement,而不是选择器(与许多其他方法一样)。确保在调用它时,使用的是ReactElement或JSX表达式。
-
请记住,此方法还基于节点的子节点的相等来确定相等。
.containsMatchingElement( patternNode ) => Boolean 匹配任意多个属性
Returns whether or not a patternNode
react element matches any element in the render tree.
-
the matches can happen anywhere in the wrapper’s contents
-
the wrapper can contain more than one node; all are searched
Otherwise, the match follows the same rules as matchesElement
.
/* Counter2component.js */
class Counter2 extends React.Component{
render(){
const num = 4;
return(
<div>
<div data-id="id" data-name="name" className="container">id</div>
</div>
)
}
}
/* test/components.test.js */
describe('测试 counter2Component 文件', function () {
const wrapper = shallow(<Counter2 />)
it('测试是否匹配任意含有的属性标签', () => {
expect(
wrapper.containsMatchingElement(<div data-id="id">id</div>)
).to.equal(true);
expect(
wrapper.containsMatchingElement(<div data-id="id" data-num="num">id</div>)
).to.equal(false); // 匹配不到 data-num="num" 属性
})
.containsAllMatchingElements(patternNodes :Array) => Boolean 匹配任意多个属性标签的数组(必须是存在的)
Returns whether or not all of the given react elements in patternNodes
match an element in the wrapper’s render tree. Every single element of patternNodes
must be matched one or more times. Matching follows the rules for containsMatchingElement
.
/* Counter2component.js */
class Counter2 extends React.Component{
render(){
<div>
<div data-id="id" data-name="name" className="container">
id
</div>
<div data-num="num">
{num}
</div>
<Counter className="foo" />
<span className="foo"></span>
</div>
}
}
/* test/components.test.js */
describe('测试 counter2Component 文件', function () {
const wrapper = shallow(<Counter2 />)
it('测试是否匹配任意含有的属性标签数组', () => {
expect(
wrapper.containsAllMatchingElements(
[<div data-id="id">id</div>,
<span></span>,
<Counter className="foo" />] // 必须是数组
)
).to.equal(true);
})
})
.containsAnyMatchingElements(patternNodes) => Boolean 匹配只要一个包含的标签数组
Returns whether or not at least one of the given react elements in patternNodes
matches an element in the wrapper’s render tree. One or more elements of patternNodes
must be matched one or more times. Matching follows the rules for containsMatchingElement
.
describe('测试 counter2Component 文件', function () {
const wrapper = shallow((
<div>
<h1>hi</h1>
<span>welcome</span>
</div>
))
it('匹配至少一个含有的标签数组', () => {
expect(
wrapper.containsAnyMatchingElements([<span>welcome</span>,<em>quite</em>])
).to.equal(true) // <span>welcome</span> 存在,<em>quite</em> 不存在
})
})
.equals( node ) => Boolean
Returns whether or not the current wrapper root node render tree looks like the one passed in.
/* pComponent.js */
class PEle extends React.Component {
render() {
return <p><span>123</span></p>;
}
}
/* test/components.test.js */
describe('测试 pComponent 文件', function () {
const wrapper = shallow(<PEle />)
it('测试',() => {
expect(
wrapper.equals(<p><span>123</span>1</p>)
).to.equal(true); // 必须完全匹配
})
})
.matchesElement(patternNode) => Boolean
Returns whether or not a given react element patternNode
matches the wrapper’s render tree. It must be a single-node wrapper, and only the root node is checked.
The patternNode
acts like a wildcard. For it to match a node in the wrapper:
- tag names must match
- contents must match: In text nodes, leading and trailing spaces are ignored, but not space in the middle. Child elements must match according to these rules, recursively.
patternNode
props (attributes) must appear in the wrapper’s nodes, but not the other way around. Their values must match if they do appear.patternNode
style CSS properties must appear in the wrapper’s node’s style, but not the other way around. Their values must match if they do appear.
describe('测试 pComponent 文件', function () {
const wrapper = shallow((
<button type="button"
style={{border:"1px solid",backgroundColor:"blcak"}}
className="btn">
hello</button>
))
it('测试标签是否匹配', () => {
expect(
wrapper.matchesElement(<button
style={{border:"1px solid",backgroundColor:"blcak"}}
className="btn">hello
</button>)
).to.equal(true);
})
})
.hasClass( className: string | RegExp ) => boolean(n)
Returns whether or not the wrapped node has a className
prop including the passed in class name. It must be a single-node wrapper.
.is( selector ) => Boolean
Returns whether or not the single wrapped node matches the provided selector. It must be a single-node wrapper.
describe('测试 counter2Component 文件', function () {
const wrapper = shallow(
<div className="foo other" />
)
it('匹配 className',() => {
expect(
wrapper.is(".other")
).to.equal(true);
})
});
.exists( [selector] ) => Boolean
Returns whether or not any nodes exist in the wrapper. Or, if a selector is passed in, whether that selector has any matches in the wrapper.
const wrapper = shallow(
<div className="foo other" />
)
it('测试某个 className 是否存在', () => {
// 两种形式等价
expect(
wrapper.exists(".foo")
).to.equal(true);
expect(
wrapper.find(".foo").exists()
).to.equal(true)
});
.isEmptyRender( ) => Boolean
Returns whether or not the wrapper would ultimately render only the allowed falsy values: false
or null
.
function Foo() {
return null;
}
const wrapper = shallow(<Foo />);
it('测试 isEmptyRender 函数',() => {
expect(
wrapper.isEmptyRender()
).to.equal(true);
})
.not( selector ) => ShallowWrapper
Returns a new wrapper with only the nodes of the current wrapper that don’t match the provided selector.
用法与 .filter
相反
const wrapper = shallow(
<div className="hello">
<span className="foo">1</span>
<span className="other">2</span>
<span className="foo">1</span>
</div>
)
it('测试 .not 函数',() => {
expect(
wrapper.find("span").not(".foo")
).to.have.lengthOf(1)
})
.children( [selector] ) => ShallowWrapper
Returns a new wrapper with all of the children of the node(s) in the current wrapper. Optionally, a selector can be provided and it will filter the children by this selector
function Box() {
return (
<ul>
<li>1</li>
<li>1</li>
<li>1</li>
<li>1</li>
</ul>
);
}
const items = [1, 2, 3, 4];
const wrapper = shallow(<Box items={items} />);
it('测试 .children 函数', () => {
expect(
wrapper.find("ul").children()
).to.have.lengthOf(items.length)
});
.childAt( index ) => ShallowWrapper
Returns a new wrapper with child at the specified index.
function Box() {
<ul>
<li>1</li>
<li>1</li>
<li>1</li>
<li>1</li>
</ul>
}
const wrapper = shallow(<Box />);
it('测试 childAt 函数',() => {
expect(
wrapper.find('ul').childAt(0).type()
).to.equal('li')
})
.parents( [selector] ) => ShallowWrapper
Returns a wrapper around all of the parents/ancestors of the single node in the wrapper. Does not include the node itself. Optionally, a selector can be provided and it will filter the parents by this selector. It must be a single-node wrapper.
function Box() {
return (
<div>
<ul>
<li>1</li>
<li>1</li>
<li>1</li>
<li>1</li>
</ul>
</div>
)
}
const wrapper = shallow(<Box />);
it('测试 childAt 函数',() => {
expect(
wrapper.find('ul').parents()
).to.lengthOf(1) // 查看父级的层数
})
.closest( selector ) => ShallowWrapper(n)
Returns a wrapper of the first element that matches the selector by traversing up through the wrapped node’s ancestors in the tree, starting with itself. It must be a single-node wrapper.
.shallow( [options] ) => ShallowWrapper
Shallow renders the root node and returns a shallow wrapper around it. It must be a single-node wrapper.
function Bar() {
return (
<div>
<div className="in-bar" />
</div>
);
}
function Foo() {
return (
<div>
<Bar />
</div>
);
}
const wrapper = shallow(<Foo />);
it('测试 shallow 函数', () => {
expect(
wrapper.find('.in-bar')
).to.have.lengthOf(0);
expect(
wrapper.find(Bar)
).to.have.lengthOf(1)
expect(
wrapper.find(Bar).shallow().find('.in-bar') // 浅渲染不能直接渲染 React 组件内部的属性, 通过 shallow 属性才能访问 React 组件内 部的属性
).to.have.lengthOf(1)
})
.render( ) => CheerioWrapper(n)
Returns a CheerioWrapper around the rendered HTML of the single node’s subtree. It must be a single-node wrapper.
.renderProp( propName )( …args ) => ShallowWrapper(n)
.unmount() => Self(n)
.text( ) => string
Returns a string of the rendered text of the current render tree. This function should be looked at with skepticism if being used to test what the actual HTML output of the component will be. If that is what you would like to test, use enzyme’s render
function instead.
Note: can only be called on a wrapper of a single node.
const wrapper = shallow(<div><b>important</b></div>);
expect(wrapper.text()).to.equal('important');
const wrapper = shallow(<div><Foo /><b>important</b></div>);
expect(wrapper.text()).to.equal('<Foo />important');
.html( ) => string
Returns a string of the rendered HTML markup of the entire current render tree (not just the shallow-rendered part). It uses static rendering internally. To see only the shallow-rendered part use .debug()
.
Note: can only be called on a wrapper of a single node.
function Foo() {
return (<div className="in-foo" />);
}
function Bar() {
return (
<div className="in-bar">
<Foo />
</div>
);
}
const wrapper = shallow(<Bar />);
expect(wrapper.html()).to.equal('<div class="in-bar"><div class="in-foo"></div></div>');
expect(wrapper.find(Foo).html()).to.equal('<div class="in-foo"></div>');
.get( index ) => ReactElement
Returns the node at a given index of the current wrapper.
function Bar(props) {
return(
<p>{this.props.name}</p>
)
}
function Foo() {
return(
<div>
<Bar name="hello" />
</div>
)
}
const wrapper = shallow(<Foo />);
it('测试 .get 函数',() => {
expect(
wrapper.find(Bar).get(0).props.name
).to.equal('hello')
})
.at( index ) => ShallowWrapper
Returns a wrapper around the node at a given index of the current wrapper.
function Bar(props) {
return(
<p>{this.props.name}</p>
)
}
function Foo() {
return(
<div>
<Bar name="hello" />
</div>
)
}
const wrapper = shallow(<Foo />);
it('测试 .get 函数',() => {
expect(
wrapper.find(Bar).at(0).props().name
).to.equal('hello')
})
.first( ) => ShallowWrapper
Reduce the set of matched nodes to the first in the set, just like .at(0)
.
function Bar(props) {
return(
<div>
<p>{this.props.name}</p>
<span>{this.props.age}</span>
</div>
)
}
function Foo() {
return(
<div>
<Bar name="hello" age="18" />
</div>
)
}
const wrapper = shallow(<Foo />);
it('测试 .get 函数',() => {
expect(
wrapper.find(Bar).first().props().name
).to.equal('hello')
})
.last( ) => ShallowWrapper
Reduce the set of matched nodes to the last in the set, just like .at(length - 1)
.
function Bar(props) {
return(
<div>
<p>{this.props.name}</p>
<span>{this.props.age}</span>
</div>
)
}
function Foo() {
return(
<div>
<Bar name="hello" age="18" />
</div>
)
}
const wrapper = shallow(<Foo />);
it('测试 .get 函数',() => {
expect(
wrapper.find(Bar).last().props().age
).to.equal('18')
})
.state( [key] ) => Any
Returns the state hash for the root node of the wrapper. Optionally pass in a prop name and it will return just that value.
key
(String
[optional]): If provided, the return value will be thethis.state[key]
of the root component instance.
class PEle extends React.Component {
constructor(props) {
super(props);
this.state = {
name: 'lili',
}
}
render() {
return <p>
<span></span>
<span className="foo"></span>
<span></span>
</p>;
}
}
const wrapper = shallow(<PEle />);
it('测试 .state 函数',() => {
expect(wrapper.state('name')).to.equal('lili')
expect(wrapper.state().name).to.equal('lili');
})
.context( [key] ) => Any(n)
Returns the context hash for the root node of the wrapper. Optionally pass in a prop name and it will return just that value.
key
(String
[optional]): If provided, the return value will be thethis.context[key]
of the root component instance.
.props( ) => Object
Returns the props object for the root node of the wrapper. It must be a single-node wrapper.
NOTE: When called on a shallow wrapper, .props()
will return values for props on the root node that the component renders, not the component itself.
This method is a reliable way of accessing the props of a node; wrapper.instance().props
will work as well, but in React 16+, stateless functional components do not have an instance. See .instance() => ReactComponent
function MyComponent(props) {
const { includedProp } = props;
return (
<div className="foo bar" includedProp={includedProp}>Hello</div>
);
}
const wrapper = shallow(<MyComponent includedProp="Success!" excludedProp="I'm not included" />);
it('测试 props 函数',() => {
expect(wrapper.props().includedProp).to.equal('Success!');
})
.prop( key ) => Any
Returns the prop value for the root node of the wrapper with the provided key. It must be a single-node wrapper.
NOTE: When called on a shallow wrapper, .prop(key)
will return values for props on the root node that the component renders, not the component itself. To return the props for the entire React component, use wrapper.instance().props
.
function MyComponent(props) {
const { includedProp } = props;
return (
<div className="foo bar" includedProp={includedProp}>Hello</div>
);
}
const wrapper = shallow(<MyComponent includedProp="Success!" excludedProp="I'm not included" />);
it('测试 props 函数', () => {
expect(wrapper.prop('includedProp')).to.equal('Success!');
})
.key( ) => String
Returns the key value for the node of the current wrapper. It must be a single-node wrapper.
const wrapper = shallow(
<ul>
{
['foo','bar'].map(item => <li key={item}>{item}</li>)
}
</ul>
).find('li')
it('测试 .key 函数',() => {
expect(
wrapper.at(0).key()
).to.equal('foo')
expect(
wrapper.last().key()
).to.equal('bar');
})
.invoke( invokePropName )( …args ) => Any(n)
.simulate( event,[ …args ] ) => Self 模拟事件(可以传入参数)
Simulate events on the root node in the wrapper. It must be a single-node wrapper.
event
(String
): The event name to be simulated...args
(Any
[optional]): A mock event object that will get passed through to the event handlers.
class Foo extends React.Component {
constructor(props) {
super(props);
this.state = { count: 0 };
}
render() {
const { count } = this.state;
return (
<div>
<div className={`clicks-${count}`}>
{count} clicks
</div>
<a href="url" onClick={() => { this.setState({ count: count + 1 }); }}>
Increment
</a>
</div>
);
}
}
const wrapper = shallow(<Foo />);
it('测试 .simulate 函数', () => {
wrapper.find('a').simulate('click');
expect(wrapper.state('count')).to.equal(1)
wrapper.find('a').simulate('click');
expect(wrapper.state('count')).to.equal(2)
})
.simulateError( error ) => Self(n)
.setState( nextState[] ) => Self 模拟 SetState 函数
A method to invoke setState()
on the root component instance, similar to how you might in the methods of the component, and re-renders. This method is useful for testing your component in hard-to-achieve states, however should be used sparingly. If possible, you should utilize your component’s external API (which is often accessible via .instance()
) in order to get it into whatever state you want to test, in order to be as accurate of a test as possible. This is not always practical, however.
NOTE: can only be called on a wrapper instance that is also the root instance.
nextState
(Object
): An object containing new state to merge in with the current statecallback
(Function
[optional]): If provided, the callback function will be executed once setState has completed
class Foo extends React.Component {
constructor(props) {
super(props);
this.state = { name: 'foo' };
}
render() {
const { name } = this.state;
return (
<div className={name} />
);
}
}
const wrapper = shallow(<Foo />);
it('测试 setState 函数', () => {
expect(wrapper.state('name')).to.equal('foo');
wrapper.setState({ age: 18 });
wrapper.setState({ name: 'bar' });
expect(wrapper.state('name')).to.equal('bar');
expect(wrapper.state('age')).to.equal(18);
})
.setProps( nextProps[, callback] ) => Self 模拟 setProps 函数
A method that sets the props of the root component, and re-renders. Useful for when you are wanting to test how the component behaves over time with changing props. Calling this, for instance, will call the componentWillReceiveProps
lifecycle method.
Similar to setState
, this method accepts a props object and will merge it in with the already existing props.
NOTE: can only be called on a wrapper instance that is also the root instance.
nextProps
(Object
): An object containing new props to merge in with the current propscallback
(Function
[optional]): If provided, the callback function will be executed once setProps has completed
function MyComponent(props) {
const { includedProp } = props;
return (
<div className="foo bar" includedProp={includedProp}>Hello</div>
);
}
const wrapper = shallow(<MyComponent includedProp="Success!" excludedProp="I'm not included" />);
it('测试 props 函数', () => {
expect(wrapper.prop('includedProp')).to.equal('Success!');
wrapper.setProps({includedProp:'hello'});
expect(wrapper.prop('includedProp')).to.equal('hello');
})
.setContext( context ) => Self
A method that sets the context of the root component, and re-renders. Useful for when you are wanting to test how the component behaves over time with changing contexts.
NOTE: can only be called on a wrapper instance that is also the root instance.
context
(Object
): An object containing new props to merge in with the current state
import PropTypes from 'prop-types';
function SimpleComponent(props, context) {
const { name } = context;
return <div>{name}</div>;
}
SimpleComponent.contextTypes = { // 必须这样写
name: PropTypes.string,
};
const context = { name: 'foo' };
const wrapper = shallow(<SimpleComponent />, { context });
it('测试 .setContext 函数', () => {
expect(wrapper.text()).to.equal('foo');
wrapper.setContext({name:'bar'});
expect(wrapper.text()).to.equal('bar');
})
.getWrapperComponent( ) => ShallowWrapper(n)
.instance( ) => ReactComponent
Returns the single-node wrapper’s node’s underlying class instance; this
in its methods.
NOTE: can only be called on a wrapper instance that is also the root instance. With React 16
and above, instance()
returns null
for stateless functional components.
function Stateless() {
return <div>Stateless</div>;
}
class Stateful extends React.Component {
render() {
return <div>Stateful</div>;
}
}
it('测试 .instance 函数在无状态组件中', () => {
const wrapper = shallow(<Stateless />);
const instance = wrapper.instance();
expect(instance).to.equal(null);
})
it('测试 .instance 函数在类组件中', () => {
const wrapper = shallow(<Stateful />);
const instance = wrapper.instance();
expect(instance).to.be.instanceOf(Stateful);
})
.update( ) => Self
Forces a re-render. Useful to run before checking the render output if something external may be updating the state of the component somewhere.
NOTE: can only be called on a wrapper instance that is also the root instance.
class ImpureRender extends React.Component {
constructor(props) {
super(props);
this.count = 0;
}
render() {
this.count += 1;
return <div>{this.count}</div>;
}
}
it('测试 update 函数', () => {
const wrapper = shallow(<ImpureRender />);
wrapper.update();
expect(wrapper.text()).to.equal('1');
})
.debug( [options] ) => String
Returns an HTML-like string of the wrapper for debugging purposes. Useful to print out to the console when tests are not passing when you expect them to.
function Book({ title, pages }) {
return (
<div>
<h1 className="title">{title}</h1>
{pages && (
<NumberOfPages
pages={pages}
object={{ a: 1, b: 2 }}
/>
)}
</div>
);
}
Book.propTypes = {
title: PropTypes.string.isRequired,
pages: PropTypes.number,
};
Book.defaultProps = {
pages: null,
};
const wrapper = shallow(<Book title="Huckleberry Finn" />);
console.log(wrapper.debug());
Outputs to console:
<div>
<h1 className="title">Huckleberry Finn</h1>
</div>
const wrapper = shallow((
<Book
title="Huckleberry Finn"
pages="633 pages"
/>
));
console.log(wrapper.debug());
Outputs to console:
<div>
<h1 className="title">Huckleberry Finn</h1>
<NumberOfPages pages="633 pages" object={{...}}/>
</div>
const wrapper = shallow((
<Book
title="Huckleberry Finn"
pages="633 pages"
/>
));
console.log(wrapper.debug({ ignoreProps: true }));
Outputs to console:
<div>
<h1>Huckleberry Finn</h1>
<NumberOfPages />
</div>
const wrapper = shallow((
<Book
title="Huckleberry Finn"
pages="633 pages"
/>
));
console.log(wrapper.debug({ verbose: true }));
Outputs to console:
<div>
<h1 className="title">Huckleberry Finn</h1>
<NumberOfPages pages="633 pages" object={{ a: 1, b: 2 }}/>
</div>
.type( ) => String | Function | null
Returns the type of the only node of this wrapper. If it’s a React component, this will be the component constructor. If it’s a native DOM node, it will be a string with the tag name. If it’s null
, it will be null
. It must be a single-node wrapper.
function Foo() {
return <div />
};
function Bar() {
return <Foo />
};
it('测试 .type 函数', () => {
const wrapper = shallow(<Foo />);
expect(
wrapper.type()
).to.equal('div')
const wrapper = shallow(<Bar />);
expect(
wrapper.type()
).to.equal(Foo)
function Null() {
return null;
}
const wrapper = shallow(<Null />);
expect(
wrapper.type()
).to.equal(null);
})
.name( ) => String | null
Returns the name of the current node of this wrapper. If it’s a composite component, this will be the name of the top-most rendered component. If it’s a native DOM node, it will be a string of the tag name. If it’s null
, it will be null
.
The order of precedence on returning the name is: type.displayName
-> type.name
-> type
.
Note: can only be called on a wrapper of a single node.
function Foo() {
return <div>
<ul>
<li>1</li>
<li>1</li>
<li>1</li>
</ul>
</div>
}
function Bar() {
return <Foo />
}
const wrapper = shallow(<div />);
expect(wrapper.name()).to.equal('div');
const wrapper = shallow(<Foo />);
expect(wrapper.name()).to.equal('div');
const wrapper = shallow(<Bar />);
expect(
wrapper.name()
).to.equal('Foo');
function Foo() {
return <div>
<ul>
<li>1</li>
<li>1</li>
<li>1</li>
</ul>
</div>
}
function Bar() {
return <Foo />
}
it('测试 .name 函数', () => {
Foo.displayName = "hello world";
function Bar() {
return <Foo />
}
const wrapper = shallow(<Bar />);
expect(
wrapper.name()
).to.equal('hello world')
})
.forEach( fn ) => Self
Iterates through each node of the current wrapper and executes the provided function with a wrapper around the corresponding node passed in as the first argument.
const wrapper = shallow((
<div>
<div className="foo" >123</div>
<div className="foo" >123</div>
<div className="foo" >123</div>
</div>
))
it('测试 .forEach 函数', () => {
wrapper.find('.foo').forEach((node) => {
expect(node.text()).to.equal('123');
expect(node.hasClass('foo')).to.equal(true);
})
})
.map( fn ) => Array
Maps the current array of nodes to another array. Each node is passed in as a ShallowWrapper
to the map function.
fn
(Function ( ShallowWrapper node, Number index ) => Any
): A mapping function to be run for every node in the collection, the results of which will be mapped to the returned array. Should expect a ShallowWrapper as the first argument, and will be run with a context of the original instance.
const wrapper = shallow((
<div>
<div className="foo">bax</div>
<div className="foo">bar</div>
<div className="foo">baz</div>
</div>
));
it('测试 .map 函数', () => {
const texts = wrapper.find('.foo').map(node => node.text());
expect(texts).to.eql(['bax', 'bar', 'baz']);
})
.reduce( fn[,initialValue] ) => Any
Applies the provided reducing function to every node in the wrapper to reduce to a single value. Each node is passed in as a ShallowWrapper
, and is processed from left to right.
fn
(Function
): A reducing function to be run for every node in the collection, with the following arguments:value
(T
): The value returned by the previous invocation of this functionnode
(ShallowWrapper
): A wrapper around the node being processedindex
(Number
): The index of the node being processed
initialValue
(T
[optional]): If provided, this will be passed in as the first argument to the first invocation of the reducing function. If omitted, the firstnode
will be provided and the iteration will begin on the second node in the collection.
function Bar(props) {
const { amount } = props;
return <div>{amount}</div>
}
function Foo() {
return (
<div>
<Bar amount={2} />
<Bar amount={4} />
<Bar amount={8} />
</div>
);
}
it('测试 .reduce 函数', () => {
const wrapper = shallow(<Foo />);
const total = wrapper.find(Bar).reduce((amount, n) => amount + n.prop('amount'), 0);
expect(total).to.equal(14);
})
.reduceRight( fn[,initialValue] ) => Any
Applies the provided reducing function to every node in the wrapper to reduce to a single value. Each node is passed in as a ShallowWrapper
, and is processed from right to left.
fn
(Function
): A reducing function to be run for every node in the collection, with the following arguments:value
(T
): The value returned by the previous invocation of this functionnode
(ShallowWrapper
): A single-node wrapper around the node being processedindex
(Number
): The index of the node being processed
initialValue
(T
[optional]): If provided, this will be passed in as the first argument to the first invocation of the reducing function. If omitted, the firstnode
will be provided and the iteration will begin on the second node in the collection.
function Foo() {
return (
<div>
<Bar amount={2} />
<Bar amount={4} />
<Bar amount={8} />
</div>
);
}
const wrapper = shallow(<Foo />);
const total = wrapper.find(Bar).reduceRight((amount, n) => amount + n.prop('amount'), 0);
expect(total).to.equal(14);
.slice( [begin[, end] ) => ShallowWrapper
Returns a new wrapper with a subset of the nodes of the original wrapper, according to the rules of Array#slice
.
begin
(Number
[optional]): Index from which to slice (defaults to0
). If negative, this is treated aslength+begin
.end
(Number
[optional]): Index at which to end slicing (defaults tolength
). If negative, this is treated aslength+end
.
const wrapper = shallow((
<div>
<div className="foo bax" />
<div className="foo bar" />
<div className="foo baz" />
</div>
));
expect(wrapper.find('.foo').slice(1)).to.have.lengthOf(2);
expect(wrapper.find('.foo').slice(1).at(0).hasClass('bar')).to.equal(true);
expect(wrapper.find('.foo').slice(1).at(1).hasClass('baz')).to.equal(true);
const wrapper = shallow((
<div>
<div className="foo bax" />
<div className="foo bar" />
<div className="foo baz" />
</div>
));
expect(wrapper.find('.foo').slice(1, 2)).to.have.lengthOf(1);
expect(wrapper.find('.foo').slice(1, 2).hasClass('bar')).to.equal(true);
.tap( intercepter ) => Self
Invokes intercepter and returns itself. intercepter is called with itself. This is helpful when debugging nodes in method chains.
intercepter
(Self
): the current ShallowWrapper instance.
const result = shallow((
<ul>
<li>xxx</li>
<li>yyy</li>
<li>zzz</li>
</ul>
)).find('li')
.tap(n => console.log(n.debug()))
.map(n => n.text());
.some( selector ) => Boolean
Returns whether or not any of the nodes in the wrapper match the provided selector.
selector
(EnzymeSelector
): The selector to match.
const wrapper = shallow((
<div>
<div className="foo qoo" />
<div className="foo boo" />
<div className="foo hoo" />
</div>
));
it('测试 .some 函数',() => {
expect(wrapper.find('.foo').some('.qoo')).to.equal(true)
expect(wrapper.find('.foo').some('.bar')).to.equal(false)
})
.someWhere( fn ) => Boolean
Returns whether or not any of the nodes in the wrapper pass the provided predicate function.
predicate
(ShallowWrapper => Boolean
): A predicate function to match the nodes.
const wrapper = shallow((
<div>
<div className="foo qoo" />
<div className="foo boo" />
<div className="foo hoo" />
</div>
));
it('测试 .someWhere 函数', () => {
expect(wrapper.find('.foo').someWhere(node => node.hasClass('hoo'))).to.equal(true);
expect(wrapper.find('.foo').someWhere(node => node.hasClass('bar'))).to.equal(false);
})
.every( selector ) => Boolean
Returns whether or not all of the nodes in the wrapper match the provided selector.
selector
(EnzymeSelector
): The selector to match.
const wrapper = shallow((
<div>
<div className="foo qoo" />
<div className="foo boo" />
<div className="foo hoo" />
</div>
));
it('测试 .someWhere 函数', () => {
expect(wrapper.find('.foo').every('.foo')).to.equal(true);
expect(wrapper.find('.foo').every('.qoo')).to.equal(false);
})
.everyWhere( fn ) => Boolean
Returns whether or not all of the nodes in the wrapper pass the provided predicate function.
predicate
(ShallowWrapper => Boolean
): A predicate function to match the nodes.
const wrapper = shallow((
<div>
<div className="foo qoo" />
<div className="foo boo" />
<div className="foo hoo" />
</div>
));
it('测试 .someWhere 函数', () => {
expect(wrapper.find('.foo').everyWhere(node => node.hasClass('foo'))).to.equal(true);
expect(wrapper.find('.foo').everyWhere(node => node.hasClass('qoo'))).to.equal(false);
})
.dive( [options] ) => ShallowWrapper 实现深层查找
Shallow render the one non-DOM child of the current wrapper, and return a wrapper around the result. It must be a single-node wrapper, and the node must be a React component.
There is no corresponding dive
method for ReactWrappers.
NOTE: can only be called on a wrapper of a single non-DOM component element node, otherwise it will throw an error. If you have to shallow-wrap a wrapper with multiple child nodes, use .shallow().
options
(Object
[optional]):options.context
: (Object
[optional]): Context to be passed into the component
function Bar() {
return (
<div>
<div className="in-bar">123123</div>
</div>
);
}
function Foo() {
return (
<div>
<Bar />
</div>
);
}
it('测试 .dive 函数',() => {
const wrapper = shallow(<Foo />);
expect(
wrapper.find('.in-bar')
).to.have.lengthOf(0)
expect(
wrapper.find(Bar).dive().find('.in-bar').text()
).to.equal('123123')
})