How to write front-end tests has always been an area of interest, and the understanding of JEST tests has always remained at the level of Expect and toBe. Learn how to test React projects using Jest+Enzyme.

Environment set up

Preparing the React Project

Create a basic React project using create-react-app. The project I use is the project of learning technology fat React learning route construction.

Setting up the Test Environment

Install dependencies:

 npm install jest --save-dev
 npm install enzyme --save-dev
 npm install enzyme-to-json --save-dev
 npm install enzyme-adapter-react-16
Copy the code

Configuration packang. Json:

  "scripts": {
    "test": "jest"
  }
Copy the code

Jest configuration file

Generate the JEST configuration file

npx jest --init
Copy the code

In the newly generated jest configuration file jest.config.js:

  rootDir: '/'.setupFiles: [
    "<rootDir>/test/setup.js"].moduleFileExtensions: [
    "js"."jsx"."ts"."tsx"."json"."node"].Copy the code

setup.jsfile

import Enzyme from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';

Enzyme.configure({ adapter: new Adapter() });
Copy the code

Import and export using ES6 will definitely be used in the test, so Babel is needed to convert the ES6 module into commonJs module.

npm install @babel/core @babel/preset-env
Copy the code

. Babelrc file

{
  "presets": ["@babel/preset-env", "@babel/preset-react"]
}
Copy the code

Write the test

Components to be tested:

// App.js
import React, { Component } from 'react';

class App extends Component {
  render() {
    return (
      <div>
        <h1>hello World</h1>
      </div>)}}export default App;
Copy the code

Test code:

//app.test.js
import React from 'react';
import App from '.. /src/App';
import { shallow } from 'enzyme'

describe('component APP test'.() = > {
  it('Test Hello World'.() = > {
    const app = shallow(<App />);
    expect(app.find('h1').text()).toBe('hello World')})})Copy the code

NPM test = NPM test

Enzymejs

The Enzyme function is to render the component to be tested so that the user can test UI rendering, DOM events, etc in the test environment.

reference

The official documentation

Commonly used API

.at(index)

It can be interpreted as returning a node based on an index. Nested ones are also included.

An 🌰

// The component to test
import React, { Component } from 'react';

class App extends Component {
  render() {
    return (
      <div>
        <h1>hello</h1>
        <h1>World</h1>
      </div>)}}export default App;

// Test the code
import React from 'react';
import App from '.. /src/App';
import { shallow } from 'enzyme'

describe('component APP test'.() = > {
  it('Test Hello World'.() = > {
    const app = shallow(<App />);
    console.log(app.find('h1').at(0))
    console.log(app.find('h1').at(1))
    expect(app.find('h1').at(0).text()).toBe('hello')
    expect(app.find('h1').at(1).text()).toBe('World')})})Copy the code

The return value:

Raise an 🌰 again

// The component to test
import React, { Component } from 'react';

class App extends Component {
  render() {
    return (
      <div>
        <h1>hello</h1>
        <h1>World</h1>
        // ********change start******
        <div>
          <h1>!!!!!</h1>
        </div>
        // ********change end******
      </div>)}}export default App;

// Test the code
import React from 'react';
import App from '.. /src/App';
import { shallow } from 'enzyme'

describe('component APP test'.() = > {
  it('Test Hello World'.() = > {
    const app = shallow(<App />);
    expect(app.find('h1').at(0).text()).toBe('hello')
    expect(app.find('h1').at(1).text()).toBe('World')
    // **********change start*********
    expect(app.find('h1').at(2).text()).toBe('. ')
     // **********change end*********})})Copy the code

Test results:

.childAt(index)

Returns a child element with the specified index to the new Wrapper.

An 🌰

// The component to test
import React, { Component } from 'react';

class App extends Component {
  render() {
    return (
      <div>
        <h1>hello</h1>
        <h1>World</h1>
      </div>)}}export default App;

// Test the code
import React from 'react';
import App from '.. /src/App';
import { shallow } from 'enzyme'

describe('component APP test'.() = > {
  it('Test Hello World'.() = > {
    const app = shallow(<App />);
    // find div, not h1
    expect(app.find('div').childAt(0).text()).toBe('hello')
    expect(app.find('div').childAt(1).text()).toBe('World')})})Copy the code

The test results

Raise an 🌰 again

The test code remains unchanged, changing the component to be tested to the following structure:

import React, { Component } from 'react'; class App extends Component { render() { return ( <div> <h1>hello</h1> <h1>World</h1> // change start------------ <div> <h1>!! </h1> </div> // change end-------------- </div> ) } } export default App;Copy the code

The test results

Conclusion: childAt should only be used for find results based on unique conditions, such as a single div.

.find(selector)

Find the node in the render tree based on the selector.

The selector parameters:

  • Tags:find('tag')
  • The name of the class:find('.className')
  • Id:.find('#id')
  • Combination:.find('tag.className')
  • Constructor:.find(Foo)
  • Component display name:.find('Foo')
  • Object property selector:.find({ prop: 'value' })

For a heap of 🌰 🌰 🌰 🌰 🌰 🌰 🌰

/ / MyCom components
import React, { Component } from 'react';
class MyCom extends Component {
  render() {
    return (
      <h1>xixi</h1>)}}export default MyCom;

// The component to test
import React, { Component } from 'react';
import MyCom from './MyCom';
class App extends Component {
  render() {
    return (
      <div>
        <h1 className='helloClass'>hello</h1>
        <h1 id="worldID">World</h1>
        <span className="spanClass">ya</span>
        <span>haha</span>
        <span fo="heheKey">hehe</span>
        <MyCom />
      </div>)}}export default App;

// Test the code
import React from 'react';
import App from '.. /src/App';
import MyCom from '.. /src/MyCom';
import { shallow } from 'enzyme'

describe('component APP test'.() = > {
  it('Test Hello World'.() = > {
    const app = shallow(<App />);
    expect(app.find('span').at(1).text()).toBe('haha')
    expect(app.find('.helloClass').text()).toBe('hello')
    expect(app.find('#worldID').text()).toBe('World')
    expect(app.find('span.spanClass').text()).toBe('ya')
    expect(app.find('MyCom').text()).toBe('<MyCom />') // Cannot match to xixi, child component is not rendered
    expect(app.find(MyCom).text()).toBe('<MyCom />')
    expect(app.find({ fo: 'heheKey' }).text()).toBe('hehe')})})Copy the code

findWhere(predicate)

Finds nodes in the render tree where the predicate returns true. The assertion function returns a nonboolean value.

An 🌰

// The component to test
import React, { Component } from 'react';
import MyCom from './MyCom';
class App extends Component {
  render() {
    return (
      <div>
        <h1 className='helloClass'>hello</h1>
        <h1 className='helloClass1'>helloyaya</h1>
        <h1 id="worldID">World</h1>
        <span className="spanClass">ya</span>
        <span>haha</span>
        <span fo="heheKey">hehe</span>
        <MyCom />
      </div>)}}export default App;

// Test the code
import React from 'react';
import App from '.. /src/App';
import MyCom from '.. /src/MyCom';
import { shallow } from 'enzyme'

describe('component APP test'.() = > {
  it('Test Hello World'.() = > {
    const app = shallow(<App />);
    const wrapper = app.findWhere(n= > n.text().indexOf('hello') > -1);
    expect(wrapper.find('.helloClass').text()).toBe('hello')
    expect(wrapper.find('.helloClass1').text()).toBe('helloyaya')})})// Test passed!!
Copy the code

The API I understand is similar to a filter in an array, where nodes that meet the criteria are filtered out and returned in a new Wrapper. We can do find again in the Wrapper returned.

.filter(selector)

Return the node matching the provided selector wrapped as a Wrapper.

An 🌰

// The component to test
import React, { Component } from 'react';
import MyCom from './MyCom';
class App extends Component {
  render() {
    return (
      <div>
        <h1 className='helloClass'>hello</h1>
        <h1 id="worldID">World</h1>
        <span className="spanClass">ya</span>
        <span>haha</span>
        <span fo="heheKey">hehe</span>
        <MyCom />
      </div>)}}export default App;
// Test the code
import React from 'react';
import App from '.. /src/App';
import { shallow } from 'enzyme'

describe('component APP test'.() = > {
  it('Test Hello World'.() = > {
    const app = shallow(<App />);
    expect(app.find('h1').filter('.helloClass').text()).toBe('hello');
    expect(app.find('h1').filter('#worldID').text()).toBe('World'); })})// The test passes
Copy the code

Summary: Filter the nodes that meet the criteria from the nodes that have been searched

.filterWhere(predicate)

Returns a node that satisfies the assertion function.

An 🌰

// The component to test
import React, { Component } from 'react';
import MyCom from './MyCom';
class App extends Component {
  render() {
    return (
      <>
        <h1 className='helloClass'>hello</h1>
        <h1 id="worldID">World</h1>
        <span className="spanClass">ya</span>
        <span>haha</span>
        <span fo="heheKey">hehe</span>
        <MyCom />
      </>)}}export default App;
// Test the code
import React from 'react';
import App from '.. /src/App';
import { shallow } from 'enzyme'

describe('component APP test'.() = > {
  it('Test Hello World'.() = > {
    const app = shallow(<App />);
    expect(app.find('h1').filterWhere(n= > n.text() === 'hello').text()).toBe('hello');

    const wrapper = app.find('span').filterWhere(n= > n.text().indexOf('h') > -1);
    expect(wrapper.at(0).text()).toBe('haha');
    expect(wrapper.at(1).text()).toBe('hehe'); })})// The test passes
Copy the code

.contains(nodeOrNodes)

Returns a Boolean value indicating whether the given node (nodeOrNodes) is present in the render tree. You can check props and corresponding values. That is, return true if the expected element has the same props and shares the same value as the wrapper element.

An 🌰

// The component to test
import React, { Component } from 'react';
import MyCom from './MyCom';
class App extends Component {
  render() {
    return (
      <div>
        <h1 className='helloClass'>hello</h1>
        <h1 id="worldID">World</h1>
        <span className="spanClass">ya</span>
        <span>haha</span>
        <span fo="heheKey">hehe</span>
        <MyCom />
      </div>)}}export default App;

// Test the code
import React from 'react';
import App from '.. /src/App';
import { shallow } from 'enzyme'

describe('component APP test'.() = > {
  it('Test Hello World'.() = > {
    const app = shallow(<App />);
    expect(app.contains(<h1>hello</h1>)).toEqual(false);
    expect(app.contains(<h1 className={'a'} >hello</h1>)).toEqual(false);
    expect(app.contains(<h1 className={'helloClass'} >Hello</h1>)).toEqual(false);
    expect(app.contains(<h1 className={'helloClass'} >hello</h1>)).toEqual(true);
    expect(app.contains(<h1 className='helloClass'>hello</h1>)).toEqual(true);

    expect(app.contains([
      <h1 id="worldID">World</h1>.<span className="spanClass">ya</span>
    ])).toEqual(true)

    expect(app.contains([
      <h1 id="worldID">World</h1>.<span>haha</span>
    ])).toEqual(false)})})Copy the code

Summary: strict matching, can not be a bit different, multiple nodes must be adjacent, otherwise it will not succeed.

.containsMatchingElement(node)

Returns a Boolean value for whether the given node exists in the shallow rendering tree.

An 🌰

// The component to test
import React, { Component } from 'react';
import MyCom from './MyCom';
class App extends Component {
  render() {
    return (
      <div>
        <h1 className='helloClass' data-fo="foo">hello</h1>
        <h1 id="worldID">World</h1>
        <span className="spanClass">ya</span>
        <span>haha</span>
        <span fo="heheKey">hehe</span>
        <MyCom />
      </div>)}}export default App;
// Test the code
import React from 'react';
import App from '.. /src/App';
import { shallow } from 'enzyme'

describe('component APP test'.() = > {
  it('Test Hello World'.() = > {
    const app = shallow(<App />);
    expect(app.containsMatchingElement(<h1>hello</h1>)).toEqual(true);
    expect(app.containsMatchingElement(<h1 className='helloClass' >hello</h1>)).toEqual(true);
    expect(app.containsMatchingElement(<h1 data-fo='foo'>hello</h1>)).toEqual(true);
    expect(app.containsMatchingElement(<h1 data-fo='foo-data'>hello</h1>)).toEqual(false);
    expect(app.containsMatchingElement(<h1 data-fo='foo' />)).toEqual(false); })})Copy the code

It comes down to this: less, not more. Props and values are completely compatible, unlike contains.

.containsAllMatchingElements(nodes)

Specifies whether all elements exist in the shallow render tree. Follow the containsMatchingElement matching principle.

An 🌰

// The component to test
import React, { Component } from 'react';
import MyCom from './MyCom';
class App extends Component {
  render() {
    return (
      <div>
        <h1 className='helloClass'>hello</h1>
        <h1 id="worldID">World</h1>
        <span className="spanClass">ya</span>
        <span>haha</span>
        <span fo="heheKey">hehe</span>
        <MyCom />
      </div>)}}export default App;

// Test the code
import React from 'react';
import App from '.. /src/App';
import { shallow } from 'enzyme'

describe('component APP test'.() = > {
  it('Test Hello World'.() = > {
    const app = shallow(<App />);
    expect(app.containsAllMatchingElements([
      <h1>hello</h1>.<h1 id="worldID">World</h1>
    ])).toEqual(true);

    expect(app.containsAllMatchingElements([
      <h1 className='helloClass'>hello</h1>.<h1 id="worldID">World</h1>
    ])).toEqual(true);

    expect(app.containsAllMatchingElements([
      <h1 className='helloClass'>hello</h1>.<span>haha</span>
    ])).toEqual(true); })})// The test passes
Copy the code

.containsAnyMatchingElements(nodes)

Returns true if there is a match in a given node.

An 🌰

// The component to test
import React, { Component } from 'react';
import MyCom from './MyCom';
class App extends Component {
  render() {
    return (
      <div>
        <h1 className='helloClass'>hello</h1>
        <h1 id="worldID">World</h1>
        <span className="spanClass">ya</span>
        <span>haha</span>
        <span fo="heheKey">hehe</span>
        <MyCom />
      </div>)}}export default App;
/ / code
import React from 'react';
import App from '.. /src/App';
import { shallow } from 'enzyme'

describe('component APP test'.() = > {
  it('Test Hello World'.() = > {
    const app = shallow(<App />);
    expect(app.containsAnyMatchingElements([
      <h1>hello</h1>.<h1 id="worldIDDDD">World</h1>
    ])).toEqual(true);

    expect(app.containsAnyMatchingElements([
      <h1 className='helloClass'>hello</h1>.<h1 id="worldIDDDD">World</h1>
    ])).toEqual(true);

    expect(app.containsAnyMatchingElements([
      <h1 className='helloClass'>hello</h1>.<span>haha</span>
    ])).toEqual(true);

    expect(app.containsAnyMatchingElements([
      <h1 className='helloClass'>hello</h1>.<span className='span'>haha</span>
    ])).toEqual(true); })})Copy the code

Contains summary: Matching rules are getting simpler

The title Match rule Detecting the Number of Nodes
contains Strict matching Single or multiple nodes (multiple nodes can be matched only if they are adjacent)
containsMatchingElement The shortest match A single
containsAllMatchingElements The shortest match Multiple (multiple nodes may not be adjacent)
containsAnyMatchingElements The shortest match Multiple (multiple nodes can not be adjacent, one of multiple nodes returns true)

.equals(node)

Returns Boolean: indicates whether the root node of the currently rendered tree is the same as the one passed in, ignoring undefined attributes.

An 🌰

// The component to test
import React, { Component } from 'react';
import MyCom from './MyCom';
class App extends Component {
  render() {
    return (
      <div>
        <h1 className='helloClass'>hello</h1>{/ *<h1 id="worldID">World</h1>
        <span className="spanClass">ya</span>
        <span>haha</span>
        <span fo="heheKey">hehe</span>
        <MyCom />* /}</div>)}}export default App;
// Test the code
import React from 'react';
import App from '.. /src/App';
import { shallow } from 'enzyme'

describe('component APP test'.() = > {
  it('Test Hello World'.() = > {
    const app = shallow(<App />);
    expect(app.equals(<div><h1 className='helloClass'>hello</h1></div>)).toEqual(true)
    expect(app.equals(<div><h1>hello</h1></div>)).toEqual(false)
    expect(app.equals(<h1 className='helloClass'>hello</h1>)).toEqual(false)
    expect(app.equals(<div></div>)).toEqual(false)})})Copy the code

Note: The test fails when the comment section of the component is uncommented

.matchesElement(node) => Boolean

The current node is in the current shallow rendering tree.

An 🌰

// The component to test
import React, { Component } from 'react';
import MyCom from './MyCom';
class App extends Component {
  render() {
    return (
      <div>
        <h1 className='helloClass'>hello</h1>{/ *<h1 id="worldID">World</h1>
        <span className="spanClass">ya</span>
        <span>haha</span>
        <span fo="heheKey">hehe</span>
        <MyCom />* /}</div>)}}export default App;
// Test the code
import React from 'react';
import App from '.. /src/App';
import { shallow } from 'enzyme'

describe('component APP test'.() = > {
  it('Test Hello World'.() = > {
    const app = shallow(<App />);
    expect(app.matchesElement(<div><h1 className='helloClass'>hello</h1></div>)).toEqual(true)
    expect(app.matchesElement(<div><h1>hello</h1></div>)).toEqual(true)
    expect(app.matchesElement(<h1>hello</h1>)).toEqual(false)
    expect(app.matchesElement(<div></div>)).toEqual(false)})})Copy the code

Note: The test fails when the component comment section is uncommented

The title Match rule
equals Strict matching
matchesElement The shortest match

But both are strict matches for nesting.

.hasClass(className) => Boolean

Is there a className

An 🌰

// The component to test
import React, { Component } from 'react';
import MyCom from './MyCom';
class App extends Component {
  render() {
    return (
      <div>
        <h1 className='helloClass'>hello</h1>
        <h1 id="worldID" className='worldClass'>World</h1>
        <span className="spanClass">ya</span>
        <span>haha</span>
        <span fo="heheKey">hehe</span>
        <MyCom />
      </div>)}}export default App;

// Test the code
import React from 'react';
import App from '.. /src/App';
import { shallow } from 'enzyme'

describe('component APP test'.() = > {
  it('Test Hello World'.() = > {
    const app = shallow(<App />);
    expect(app.find('h1').at(0).hasClass('helloClass')).toEqual(true);
    expect(app.find('#worldID').hasClass('worldClass')).toEqual(true); })})Copy the code

.is(selector) => Boolean

Returns whether a single wrapper node matches the provided selector. It must be a single-node wrapper.

An 🌰

// The component to test
import React, { Component } from 'react';
import MyCom from './MyCom';
class App extends Component {
  render() {
    return (
      <h1 className='helloClass'>hello</h1>)}}export default App;

// Test the code
import React from 'react';
import App from '.. /src/App';
import { shallow } from 'enzyme'

describe('component APP test'.() = > {
  it('Test Hello World'.() = > {
    const app = shallow(<App />);
    expect(app.is('.helloClass')).toEqual(true);
    expect(app.is('h1')).toEqual(true); })})Copy the code

Raise an 🌰 again

// The component to test
import React, { Component } from 'react';
import MyCom from './MyCom';
class App extends Component {
  render() {
    return (
      <div>
        <h1 className='helloClass'>hello</h1>
      </div>)}}export default App;
// Test the code
import React from 'react';
import App from '.. /src/App';
import { shallow } from 'enzyme'

describe('component APP test'.() = > {
  it('Test Hello World'.() = > {
    const app = shallow(<App />);
    expect(app.is('.helloClass')).toEqual(false);
    expect(app.is('h1')).toEqual(false);
    expect(app.is('div')).toEqual(true); })})Copy the code

.exists() => Boolean

Whether the current node exists

An 🌰

// The component to test
import React, { Component } from 'react';
import MyCom from './MyCom';
class App extends Component {
  render() {
    return (
      <div>
        <h1 className='helloClass'>hello</h1>
        <h1 id="worldID" className='worldClass'>World</h1>
        <span className="spanClass">ya</span>
        <span>haha</span>
        <span fo="heheKey">hehe</span>
        <MyCom />
      </div>)}}export default App;

// Test the code
import React from 'react';
import App from '.. /src/App';
import { shallow } from 'enzyme'

describe('component APP test'.() = > {
  it('Test Hello World'.() = > {
    const app = shallow(<App />);
    expect(app.exists('.helloClass')).toEqual(true);
    expect(app.find('#worldID').exists()).toEqual(true); })})Copy the code

.not(selector) => ShallowWrapper

Removes nodes in the current Wrapper that match the provided selector. (As opposed to.filter())

An 🌰

// The component to test
import React, { Component } from 'react';
import MyCom from './MyCom';
class App extends Component {
  render() {
    return (
      <div>
        <h1 className='helloClass'>hello</h1>
        <h1 id="worldID" className='worldClass'>World</h1>
        <span className="spanClass">ya</span>
        <span>haha</span>
        <span fo="heheKey">hehe</span>
        <MyCom />
      </div>)}}export default App;
// Test the code
import React from 'react';
import App from '.. /src/App';
import { shallow } from 'enzyme'

describe('component APP test'.() = > {
  it('Test Hello World'.() = > {
    const app = shallow(<App />);
    expect(app.find('h1').not('.helloClass').text()).toBe('World')})})Copy the code

.children() => ShallowWrapper

Gets wrappers for all child nodes in the current Wrapper.

🌰 🌰 🌰

// The component to test
import React, { Component } from 'react';
import MyCom from './MyCom';
class App extends Component {
  render() {
    return (
      <div>
        <h1 className='helloClass'>hello</h1>
        <h1 id="worldID" className='worldClass'>World</h1>
        <span className="spanClass">ya</span>
        <span>haha</span>
        <span fo="heheKey">hehe</span>
        <MyCom />
      </div>)}}export default App;
// Test the code
import React from 'react';
import App from '.. /src/App';
import { shallow } from 'enzyme'

describe('component APP test'.() = > {
  it('Test Hello World'.() = > {
    const app = shallow(<App />);
    expect(app.find('div').children()).toHaveLength(6)
    expect(app.find('h1').children()).toHaveLength(2)
    expect(app.find('h1').children().at(0).text()).toBe('hello')
    expect(app.find('h1').children().at(1).text()).toBe('World')})})Copy the code

.childAt(index) => ShallowWrapper

Returns a Wrapper for the child element with the specified index

🌰 🌰 🌰

// The component to test
import React, { Component } from 'react';
import MyCom from './MyCom';
class App extends Component {
  render() {
    return (
      <div>
        <h1 className='helloClass'>hello</h1>
        <h1 id="worldID" className='worldClass'>World</h1>
        <span className="spanClass">ya</span>
        <span>haha</span>
        <span fo="heheKey">hehe</span>
        <MyCom />
      </div>)}}export default App;
// Test the code
import React from 'react';
import App from '.. /src/App';
import { shallow } from 'enzyme'

describe('component APP test'.() = > {
  it('Test Hello World'.() = > {
    const app = shallow(<App />);
    expect(app.find('div').childAt(0).text()).toBe('hello')
    // expect(app.find('h1').childAt(1)).toBe('World')
    "ChildAt" is meant to be run on 1 node. 2 found instead.})})Copy the code

.parents() => ShallowWrapper

Gets all the parents of the current node

🌰 🌰 🌰

// The component to test
import React, { Component } from 'react';
import MyCom from './MyCom';
class App extends Component {
  render() {
    return (
      <div>
        <h1>
          <p>haha</p>
        </h1>
        <span>xixi</span>
      </div>)}}export default App;
// Test the code
import React from 'react';
import App from '.. /src/App';
import { shallow } from 'enzyme'

describe('component APP test'.() = > {
  it('Test Hello World'.() = > {
    const app = shallow(<App />);
    expect(app.find('p').parents()).toHaveLength(2)
    expect(app.find('span').parents()).toHaveLength(1)})})Copy the code

.parent() => ShallowWrapper

Gets the immediate parent of the current node

🌰 🌰 🌰

// The component to test
import React, { Component } from 'react';
class App extends Component {
  render() {
    return (
      <div>
        <h1>
          <p>haha</p>
        </h1>
        <span>xixi</span>
      </div>)}}export default App;
// Test the code
import React from 'react';
import App from '.. /src/App';
import { shallow } from 'enzyme'

describe('component APP test'.() = > {
  it('Test Hello World'.() = > {
    const app = shallow(<App />);
    expect(app.find('p').parent()).toHaveLength(1)
    expect(app.find('span').parent()).toHaveLength(1)})})Copy the code

.closest(selector) => ShallowWrapper

Returns the node that matches the current selector by traversing up from itself. Must be a single-node wrapper.

🌰 🌰 🌰

// The component to test
import React, { Component } from 'react';
import MyCom from './MyCom';
class App extends Component {
  render() {
    return (
      <span className='calss1'>
        <h1>
          <p>haha</p>
        </h1>
        <span>xixi</span>{/ *<p className='class2'>hehe</p>* /}</span>)}}export default App;
// Test the code
import React from 'react';
import App from '.. /src/App';
import { shallow } from 'enzyme'

describe('component APP test'.() = > {
  it('Test Hello World'.() = > {
    const app = shallow(<App />);
    expect(app.find('p').closest('.calss1').children().at(1).text()).toBe('xixi')})})Copy the code

An error is reported when the comment part of a component is uncommented:

You should ensure that the lookup node (p) is a single node.

.shallow([options]) => ShallowWrapper

Shallow render of the current component to generate the virtual DOM.

.render() => CheerioWrapper

Returns CheerioWrapper for the subtree of the current node

.unmount() => ShallowWrapper

A way to unload components. This can be used to simulate components that go through the uninstall/install life cycle.

.text() => String

Returns a string representation of this node in the current render tree.

.html() => String

Returns a static HTML rendering of the current node

🌰 🌰 🌰

// The component to test
import React, { Component } from 'react';
import MyCom from './MyCom';
class App extends Component {
  render() {
    return (
      <span className='calss1'>
        <h1>
          <p>haha</p>
        </h1>
        <span>xixi</span>
        <p className='class2'>hehe</p>
      </span>)}}export default App;
// Test the code
import React from 'react';
import App from '.. /src/App';
import { shallow } from 'enzyme'

describe('component APP test'.() = > {
  it('Test Hello World'.() = > {
    const app = shallow(<App />);
    console.log(app.find('.class2').html())
  })
})
Copy the code

Test results:

.get(index) => ReactElement

Returns the index node ReactElement

🌰 🌰 🌰

// The component to test
import React, { Component } from 'react';
import MyCom from './MyCom';
class App extends Component {
  render() {
    return (
      <div className='calss1'>
        <h1>
          <p>haha</p>
        </h1>
        <span foo='foo-data'>xixi</span>
        <p className='class2'>hehe</p>
      </div>)}}export default App;
// Test the code
import React from 'react';
import App from '.. /src/App';
import { shallow } from 'enzyme'

describe('component APP test'.() = > {
  it('Test Hello World'.() = > {
    const app = shallow(<App />);
    expect(app.find('div').children().get(1).props.foo).toBe('foo-data')})})Copy the code

Can be used to test props parameters.

.at(index) => ShallowWrapper

Returns the node based on the index.

🌰 🌰 🌰

// The component to test
import React, { Component } from 'react';
class App extends Component {
  render() {
    return (
      <div className='calss1'>
        <h1>
          <p>haha</p>
        </h1>
        <span foo='foo-data'>xixi</span>
        <p className='class2'>hehe</p>
      </div>)}}export default App;

// Test the code
import React from 'react';
import App from '.. /src/App';
import { shallow } from 'enzyme'

describe('component APP test'.() = > {
  it('Test Hello World'.() = > {
    const app = shallow(<App />);
    expect(app.find('p')
    .at(0)
    .text()).toBe('haha')})})// The test passes
Copy the code

.first() => ShallowWrapper

Returns the wrapper for the current first node

🌰 🌰 🌰

// The component to test
import React, { Component } from 'react';
class App extends Component {
  render() {
    return (
      <div className='calss1'>
        <h1>
          <p>haha</p>
        </h1>
        <span foo='foo-data'>xixi</span>
        <p className='class2'>hehe</p>
      </div>)}}export default App;
// Test the code
import React from 'react';
import App from '.. /src/App';
import { shallow } from 'enzyme'

describe('component APP test'.() = > {
  it('Test Hello World'.() = > {
    const app = shallow(<App />);
    expect(app.find('p')
    .first()
    .text()).toBe('haha')})})Copy the code

.last() => ShallowWrapper

Returns the wrapper for the current last node

🌰 🌰 🌰

// The component to test
import React, { Component } from 'react';
class App extends Component {
  render() {
    return (
      <div className='calss1'>
        <h1>
          <p>haha</p>
        </h1>
        <span foo='foo-data'>xixi</span>
        <p className='class2'>hehe</p>
      </div>)}}export default App;
// Test the code
import React from 'react';
import App from '.. /src/App';
import { shallow } from 'enzyme'

describe('component APP test'.() = > {
  it('Test Hello World'.() = > {
    const app = shallow(<App />);
    expect(app.find('p')
    .last()
    .text()).toBe('hehe')})})Copy the code

.state([key]) => Any

Returns the state of the root component. This can only be applied to the same component and will cause an error if used on a node of Find. ShallowWrapper::state() can only be called on the root

🌰 🌰 🌰

// The component to test
import React, { Component } from 'react';
class App extends Component {
  constructor(props) {
    super(props);
    this.state = {
      name: 'jerry'.age: 23}}render() {
    return (
      <div className='calss1'>
        <h1>
          <p>haha</p>
          <span>enen</span>
        </h1>
        <span foo='foo-data'>xixi</span>
        <p className='class2'>hehe</p>
      </div>)}}export default App;
// Test the code
import React from 'react';
import App from '.. /src/App';
import { shallow } from 'enzyme'

describe('component APP test'.() = > {
  it('Test Hello World'.() = > {
    const app = shallow(<App />);
    expect(app.state('name')).toBe('jerry')})})Copy the code

.context([key]) => Any

Returns the context of the root component

.props() => Object

Returns the props of the current node

🌰 🌰 🌰

// The component to test
import React, { Component } from 'react';
class App extends Component {
  render() {
    return (
      <div className='calss1'>
        <h1>
          <p>haha</p>
          <span>enen</span>
        </h1>
        <span foo='foo-data'>xixi</span>
        <p className='class2'>hehe</p>
      </div>)}}export default App;
// Test the code
import React from 'react';
import App from '.. /src/App';
import { shallow } from 'enzyme'

describe('component APP test'.() = > {
  it('Test Hello World'.() = > {
    const app = shallow(<App />);
    console.log(app.find("span").at(1).props());
    // { foo: 'foo-data', children: 'xixi' }})})Copy the code

.prop(key) => Any

Returns the value of a (key) property of the current node props

🌰 🌰 🌰

// The component to test
import React, { Component } from 'react';
class App extends Component {
  render() {
    return (
      <div className='calss1'>
        <h1>
          <p>haha</p>
          <span>enen</span>
        </h1>
        <span foo='foo-data'>xixi</span>
        <p className='class2'>hehe</p>
      </div>)}}export default App;

// Test the code
import React from 'react';
import App from '.. /src/App';
import { shallow } from 'enzyme'

describe('component APP test'.() = > {
  it('Test Hello World'.() = > {
    const app = shallow(<App />);
    expect(app.find("span").at(1).prop('foo')).toBe('foo-data'); })})Copy the code

.key() => String

Returns the key of the current node.

🌰 🌰 🌰

// The component to test
import React, { Component } from 'react';
class App extends Component {
  render() {
    return (
      <div className='calss1'>
        <h1 key='h1Key'>
          <p>haha</p>
          <span>enen</span>
        </h1>
        <span foo='foo-data'>xixi</span>
        <p className='class2'>hehe</p>
      </div>)}}export default App;
// Test the code
import React from 'react';
import App from '.. /src/App';
import { shallow } from 'enzyme'

describe('component APP test'.() = > {
  it('Test Hello World'.() = > {
    const app = shallow(<App />);
    expect(app.find("h1").key()).toBe('h1Key'); })})Copy the code

.simulate(event[, data]) => ShallowWrapper

Simulate events on the current node

🌰 🌰 🌰

The following components exist:

import React, { Component } from 'react';
class App extends Component {
  constructor(props) {
    super(props);
    this.state = {
      count: 0
    }
  }
  handleClick = () = > {
    this.setState({
      count: this.state.count + 1})}render() {
    return (
      <div className='calss1'>
        <button onClick={this.handleClick}>increase</button>
      </div>)}}export default App;
Copy the code

We need to test the following contents:

  1. Click on theincreaseButton triggers click event —simulate
  2. Test the state after the click eventcountWhether to add 1
// Test the code
import React from 'react';
import App from '.. /src/App';
import { shallow } from 'enzyme'

describe('component APP test'.() = > {
  it('Test Hello World'.() = > {
    const app = shallow(<App />);
    expect(app.state("count")).toBe(0)
    const btn = app.find('button');
    btn.simulate('click');
    expect(app.state('count')).toBe(1)})})Copy the code

.setState(nextState) => ShallowWrapper

Manually setState updates the root component state

🌰 🌰 🌰

// The component to test
import React, { Component } from 'react';
class App extends Component {
  constructor(props) {
    super(props);
    this.state = {
      count: 0
    }
  }
  handleClick = () = > {
    this.setState({
      count: this.state.count + 1})}render() {
    return (
      <div className='calss1'>
        <button onClick={this.handleClick}>increase</button>
      </div>)}}export default App;
// Test the code
import React from 'react';
import App from '.. /src/App';
import { shallow } from 'enzyme'

describe('component APP test'.() = > {
  it('Test Hello World'.() = > {
    const app = shallow(<App />);
    expect(app.state('count')).toBe(0);
    app.setState({count:5})
    expect(app.state('count')).toBe(5)})})Copy the code

.setProps(nextProps) => ShallowWrapper

Manually update the props of the root component

🌰 🌰 🌰

// The component to test
import React, { Component } from 'react';
class App extends Component {
  render() {
    return (
      <div className='calss1'>
        <p>hi:{this.props.name}</p>
      </div>)}}export default App;

// Test the code
import React from 'react';
import App from '.. /src/App';
import { shallow } from 'enzyme'

describe('component APP test'.() = > {
  it('Test Hello World'.() = > {
    const app = shallow(<App name='jerry' />);
    expect(app.find('p').text()).toBe('hi:jerry');
    app.setProps({name:'tom'});
    expect(app.find('p').text()).toBe('hi:tom')})})Copy the code

.setContext(context) => ShallowWrapper

Manually set the context of the root component

.instance() => ReactComponent

Returns an instance of the root component

🌰 🌰 🌰

// The component to test
import React, { Component } from 'react';
class App extends Component {
  render() {
    return (
      <div className='calss1'>
        <p>hi:{this.props.name}</p>
      </div>)}}export default App;
// Test the code
import React from 'react';
import App from '.. /src/App';
import { shallow } from 'enzyme'

describe('component APP test'.() = > {
  it('Test Hello World'.() = > {
    const app = shallow(<App name='jerry' />);
    console.log(app.instance())
  })
})
Copy the code

Note: This can only be called on the wrapper instance of the root instance. In React 16 and later, instance() returns NULL for stateless functionality components.

.update() => ShallowWrapper

Call.forceUpdate() on the root component instance

.debug() => String

Returns a string representation of the current shallow rendering tree for debugging purposes

🌰 🌰 🌰

// The component to test
import React, { Component } from 'react';
class App extends Component {
  render() {
    return (
      <div className='calss1'>
        <p>hi:{this.props.name}</p>
      </div>)}}export default App;
// Test the code
import React from 'react';
import App from '.. /src/App';
import { shallow } from 'enzyme'

describe('component APP test'.() = > {
  it('Test Hello World'.() = > {
    const app = shallow(<App name='jerry' />);
    console.log(app.debug())
  })
})
Copy the code

.type() => String|Function

Returns the type of the wrapper’s current node.

🌰 🌰 🌰

// The component to test
import React, { Component } from 'react';
class App extends Component {
  render() {
    return (
      <div className='calss1'>
        <p>hi:{this.props.name}</p>
      </div>)}}export default App;
// Test the component
import React from 'react';
import App from '.. /src/App';
import { shallow } from 'enzyme'

describe('component APP test'.() = > {
  it('Test Hello World'.() = > {
    const app = shallow(<App name='jerry' />);
    expect(app.find('p').type()).toBe("p")
    expect(app.find('div').type()).toBe('div')})})Copy the code

.name() => String

Returns the name of the current node

🌰 🌰 🌰

// The component to test
import React, { Component } from 'react';
class App extends Component {
  render() {
    return (
      <div className='calss1'>
        <p>hi:{this.props.name}</p>
      </div>)}}export default App;
// Test the code
import React from 'react';
import App from '.. /src/App';
import { shallow } from 'enzyme'

describe('component APP test'.() = > {
  it('Test Hello World'.() = > {
    const app = shallow(<App name='jerry' />);
    expect(app.find('p').name()).toBe("p")
    expect(app.find('div').name()).toBe('div')})})Copy the code

.forEach(fn) => ShallowWrapper

Iterate over each node currently and execute the provided function

🌰 🌰 🌰

// The component to test
import React, { Component } from 'react';
class App extends Component {
  render() {
    return (
      <div className='calss1'>
        <div className="foo bax" />
        <div className="foo bar" />
        <div className="foo baz" />
      </div>)}}export default App;
// Test the code
import React from 'react';
import App from '.. /src/App';
import { shallow } from 'enzyme'

describe('component APP test'.() = > {
  it('Test Hello World'.() = > {
    const app = shallow(<App name='jerry' />);
    const wrappers = app.find('.calss1').children();
    wrappers.forEach(e= >{
      expect(e.hasClass('foo')).toEqual(true); })})})Copy the code

.map(fn) => Array

Maps the current node array to another array

🌰 🌰 🌰

// The component to test
import React, { Component } from 'react';
class App extends Component {
  render() {
    return (
      <div className='calss1'>
        <div className="foo bax" >a</div>
        <div className="foo bar" >b</div>
        <div className="foo baz bar" >c</div>
      </div>)}}export default App;
// Test the code
import React from 'react';
import App from '.. /src/App';
import { shallow } from 'enzyme'

describe('component APP test'.() = > {
  it('Test Hello World'.() = > {
    const app = shallow(<App name='jerry' />);
    const wrappers = app.find('.calss1').children();
    const map_wrappers = wrappers.map(e= > e.hasClass('bar'));
    expect(map_wrappers).toEqual([false.true.true]);

    const text_wrappers = wrappers.map(e= >e.text());
    expect(text_wrappers).toEqual(['a'.'b'.'c'])})})Copy the code

.reduce(fn[, initialValue]) => Any

Apply the supplied reduction function to each node in the wrapper to reduce to a single value. Each node is passed in as a ShallowWrapper and processed from left to right.

  1. Function: A reduction function run for each node in the collection, with the following parameters:
    • Value: The value returned from the last call to this function
    • Node: node wrapper being processed
    • Index: indicates the index of the node being processed
  2. InitialValue: If provided, this will be passed as the first argument to reduce the first call to the function. If omitted, the first node is supplied, and the iteration begins with the second node in the collection.

🌰 🌰 🌰

// The component to test
import React, { Component } from 'react';
class App extends Component {
  render() {
    return (
      <div className='calss1'>
        <div className="foo" count={2}>a</div>
        <div className="foo" count={12}>b</div>
        <div className="foo" count={14}>c</div>
      </div>)}}export default App;
// Test the code
import React from 'react';
import App from '.. /src/App';
import { shallow } from 'enzyme'

describe('component APP test'.() = > {
  it('Test Hello World'.() = > {
    const app = shallow(<App name='jerry' />);
    const wrappers = app.find('.foo');
    const totalCount = wrappers.reduce((count, n) = > count + n.prop('count'), 0);

    expect(totalCount).toEqual(28);
    const totalCount1 = wrappers.reduce((count, n) = > count + n.prop('count'));
    expect(totalCount1).toEqual("[object Object]1214")})})Copy the code

.reduceRight(fn[, initialValue]) => Any

Reduces the current node array to one value from right to left. Reduce is from left to right, and this is from right to left.

.slice([begin[, end]]) => ShallowWrapper

Returns a new wrapper for a subset of the nodes with the original wrapper according to the rules of Array’s slice.

🌰 🌰 🌰

// The component to test
import React, { Component } from 'react';
class App extends Component {
  render() {
    return (
      <div className='calss1'>
        <div className="foo" count={2}>a</div>
        <div className="foo" count={12}>b</div>
        <div className="foo" count={14}>c</div>
      </div>)}}export default App;
// Test the code
import React from 'react';
import App from '.. /src/App';
import { shallow } from 'enzyme'

describe('component APP test'.() = > {
  it('Test Hello World'.() = > {
    const app = shallow(<App name='jerry' />);
    const wrappers = app.find('.foo');
    const slice_wrapper = wrappers.slice(1.2);
    const text = slice_wrapper.map(e= >e.text())
    expect(text).toEqual(['b'])})})Copy the code

.tap(intercepter) => Self

Click on the Wrapper method chain. Helps with debugging.

🌰 🌰 🌰

// The component to test
import React, { Component } from 'react';
class App extends Component {
  render() {
    return (
      <div className='calss1'>
        <div className="foo" count={2}>a</div>
        <div className="foo" count={12}>b</div>
        <div className="foo" count={14}>c</div>
      </div>)}}export default App;
// Test the code
import React from 'react';
import App from '.. /src/App';
import { shallow } from 'enzyme'

describe('component APP test'.() = > {
  it('Test Hello World'.() = > {
    const app = shallow(<App name='jerry' />);
    const wrappers = app.find('.foo');
    
    const result= wrappers.tap(n= >console.log(n.debug())).map(n= >n.text());
    expect(result).toEqual(['a'.'b'.'c'])})})Copy the code

.some(selector) => Boolean

Returns whether any nodes in the render tree match the provided selector.

// The component to test
import React, { Component } from 'react';
class App extends Component {
  render() {
    return (
      <div className='calss1'>
        <div className="foo" id='aId' count={2}>a</div>
        <div className="foo" count={12}>b</div>
        <div className="foo" count={14}>c</div>
      </div>)}}export default App;
// Test the code
import React from 'react';
import App from '.. /src/App';
import { shallow } from 'enzyme'

describe('component APP test'.() = > {
  it('Test Hello World'.() = > {
    const app = shallow(<App name='jerry' />);
    const wrappers = app.find('.foo');
    expect(wrappers.some('#aId')).toEqual(true)})})Copy the code

.someWhere(predicate) => Boolean

Returns whether any nodes in the render tree match the provided assertion function. Some is a functional representation of some, for example, when it needs to be processed and then asserted.

🌰 🌰 🌰

// The component to test
import React, { Component } from 'react';
class App extends Component {
  render() {
    return (
      <div className='calss1'>
        <div className="foo bar" count={2}>a</div>
        <div className="foo" count={12}>b</div>
        <div className="foo" count={14}>c</div>
      </div>)}}export default App;
// Test the code
import React from 'react';
import App from '.. /src/App';
import { shallow } from 'enzyme'

describe('component APP test'.() = > {
  it('Test Hello World'.() = > {
    const app = shallow(<App name='jerry' />);
    const wrappers = app.find('.foo');
    expect(wrappers.someWhere(n= > n.hasClass('bar'))).toEqual(true)})})Copy the code

.every(selector) => Boolean

Returns whether all nodes in the render tree match the provided selector.

🌰 🌰 🌰

// The component to test
import React, { Component } from 'react';
class App extends Component {
  render() {
    return (
      <div className='calss1'>
        <div className="foo bar" count={2}>a</div>
        <div className="foo boo" count={12}>b</div>
        <div className="foo aoo" count={14}>c</div>
      </div>)}}export default App;
// Test the code
import React from 'react';
import App from '.. /src/App';
import { shallow } from 'enzyme'

describe('component APP test'.() = > {
  it('Test Hello World'.() = > {
    const app = shallow(<App name='jerry' />);
    const wrappers = app.find('.foo');
    expect(wrappers.every('.bar')).toEqual(false);
    expect(wrappers.every('.boo')).toEqual(false);
    expect(wrappers.every('.foo')).toEqual(true); })})Copy the code

.everyWhere(predicate) => Boolean

Returns whether all nodes satisfy the provided assertion function.

🌰 🌰 🌰

// The component to test
import React, { Component } from 'react';
class App extends Component {
  render() {
    return (
      <div className='calss1'>
        <div className="foo bar" count={2}>a</div>
        <div className="foo boo" count={12}>b</div>
        <div className="foo aoo" count={14}>c</div>
      </div>)}}export default App;
// Test the code
import React from 'react';
import App from '.. /src/App';
import { shallow } from 'enzyme'

describe('component APP test'.() = > {
  it('Test Hello World'.() = > {
    const app = shallow(<App name='jerry' />);
    const wrappers = app.find('.foo');
    expect(wrappers.everyWhere(n= >n.hasClass('bar'))).toEqual(false);
    expect(wrappers.everyWhere(n= >n.hasClass('boo'))).toEqual(false);
    expect(wrappers.everyWhere(n= >n.hasClass('foo'))).toEqual(true); })})Copy the code

.dive([options]) => ShallowWrapper

Shallow renders a non-DOM child of the current Wrapper and returns a Wrapper around the result, which must be a single-node wrapper.

🌰 🌰 🌰

// The component to test
import React, { Component } from 'react';
import MyCom from './MyCom'
class App extends Component {
  render() {
    return (
      <div className='calss1'>
        <div className="foo bar" count={2}>a</div>
        <MyCom />
      </div>)}}export default App;

// MyCom
import React, { Component } from 'react';
class MyCom extends Component {
  render() {
    return (
      <h1>xixi</h1>)}}export default MyCom;

// Test the code

import React from 'react';
import App from '.. /src/App';
import { shallow } from 'enzyme'

describe('component APP test'.() = > {
  it('Test Hello World'.() = > {
    const app = shallow(<App name='jerry' />);
    const wrapper = app.find('MyCom');
    expect(wrapper.text()).toBe('<MyCom />');
    // expect(wrapper.find('h1').text()).toBe('xixi')
    // Method "text" is meant to be run on 1 node. 0 found instead
    expect(wrapper.dive().find('h1').text()).toBe('xixi')})})Copy the code

Can only be called on the wrapper of a single non-DOM component element node, otherwise an error will be thrown. If you must shallow wrap a wrapper with multiple child nodes, use.shallow().

Shallow does not render out the child component, so it cannot find the contents of the child component, as dive() does.