ruk·si

⚛️ React
Testing

Updated at 2017-08-04 20:29

React component testing is commonly done using Enzyme. Enzyme is a JavaScript testing utility that makes it easier to assert and manipulate React components.

# React >=15.5
npm install enzyme enzyme-wait react-test-renderer react-dom --save-dev

Enzyme has three different render wrappers:

  • shallow does shallow rendering, so doesn't render any children,
  • mount does full rendering, so renders children.
  • render does static rendering. Calls render and renders all children. This is mainly used only with static websites as doesn't call some life cycle methods and doesn't allow prop changing.
import {shallow, mount, render} from 'enzyme';

const wrapper = shallow(<Foo />);
const wrapper = mount(<Foo />);
const wrapper = render(<Foo />);

You can modify the component with setProps, setState and setContext. They will trigger a new render.

import PropTypes from 'prop-types';

function Foo({ name }) {
  return (
    <div className={name} />
  );
}
Foo.propTypes = {
  name: PropTypes.string.isRequired,
};

const wrapper = shallow(<Foo name="foo" />);
expect(wrapper.find('.foo')).to.have.length(1);
expect(wrapper.find('.bar')).to.have.length(0);
wrapper.setProps({ name: 'bar' });
expect(wrapper.find('.foo')).to.have.length(0);
expect(wrapper.find('.bar')).to.have.length(1);

const spy = sinon.spy(MyComponent.prototype, 'componentWillReceiveProps');

const wrapper = shallow(<MyComponent foo="bar" />);
expect(spy.calledOnce).to.equal(false);
wrapper.setProps({ foo: 'foo' });
expect(spy.calledOnce).to.equal(true);

You can also wait for rendering of a specific component or CSS selector.

import {createWaitForElement} from 'enzyme-wait';
const wait = createWaitForElement(YourComponent);
wait.then(() => {});

If we have two components O (Outer) and I (Inner), here is how all of the different rendering wrappers work with the following sequence:

const wrapper = *METHOD*(<Outer ***/>)
wrapper.setProps(***)
wrapper.unmount()
SHALLOW:
    O>>constructor
    O>>componentWillMount
    O>>render
    O>>componentWillReceiveProps
    O>>render
    O>>componentWillUnmount

MOUNT:
    O>>constructor
    O>>componentWillMount
    O>>render
        I>>>>constructor
        I>>>>componentWillMount
        I>>>>render
        I>>>>componentDidMount
    O>>componentDidMount
    O>>componentWillReceiveProps
    O>>render
        I>>>>componentWillReceiveProps
        I>>>>render
    O>>componentWillUnmount
        I>>>>componentWillUnmount

RENDER:
    O>>constructor
    O>>componentWillMount
    O>>render
        I>>>>constructor
        I>>>>componentWillMount
        I>>>>render

Sources