enzyme

Test Utilities

安装

  1. 引入 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.

  1. key (String [optional]): If provided, the return value will be the this.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.

  1. key (String [optional]): If provided, the return value will be the this.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.

  1. event (String): The event name to be simulated
  2. ...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.

  1. nextState (Object): An object containing new state to merge in with the current state
  2. callback (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 componentWillReceivePropslifecycle 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.

  1. nextProps (Object): An object containing new props to merge in with the current props
  2. callback (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.

  1. 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.

  1. 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.

  1. 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 function
    • node (ShallowWrapper): A wrapper around the node being processed
    • index (Number): The index of the node being processed
  2. 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 first node 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.

  1. 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 function
    • node (ShallowWrapper): A single-node wrapper around the node being processed
    • index (Number): The index of the node being processed
  2. 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 first node 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.

  1. begin (Number [optional]): Index from which to slice (defaults to 0). If negative, this is treated as length+begin.
  2. end (Number [optional]): Index at which to end slicing (defaults to length). If negative, this is treated as length+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.

  1. 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.

  1. 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.

  1. 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.

  1. 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.

  1. 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().

  1. options (Object [optional]):
  2. 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')
  })
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值