Unit Testing in React

General advices

Why Test

Main reasons:

  • to make sure the app works as it should
  • gives more confidence


Advantages:

  • code refactoring without breaking anything
    • adding new features, tweaking existing ones
    • make sure you don't break some other part of the app

What's Worth Testing

  • start with high-value items
  • anything that accepts user input
    • form validation
    • error handling
  • edge cases
  • utility functions

What to Test

  • that the comp. renders (without errors)
  • that it renders the expected things
  • all the variables in state
    • className if it depends on state
    • styles if they depend on state
    • conditionally rendered children
  • events
    • the callback was called with the correct args
  • edge cases
    • especially when working with list of items
    • different values for the props
      • null, undefined, empty array/object

How to Test

Shallow rendering:

  • renders only one level of components
    • makes sure children don't affect assertions
    • decouples the components

 

Using mount:

  • needs a browser env.
  • can be used to test the lifecycle of the comp.

Testing Redux

  • the actions and reducers should be tested separately
    • reducers are easy to test because they are pure functions
    • for actions we need to mock the REST library
  • the actions should be injected in the comp. using DI
    • something like InversifyJS
  • when testing a comp, check that the action was called with the correct arguments

Useful Patterns

// finding a HTML element
const wrapper: ShallowWrapper = shallow(<App/>);
expect(wrapper.find("h1")).to.have.length(1);

// finding a React component
expect(wrapper.find(ProductList)).to.have.length(1);

// contains the an element
expect(wrapper.contains(<span className="num-items">{0}</span>)).to.equal(true);

// check a click event
const noneRadio: ShallowWrapper= wrapper.find("input[value='none']");

noneRadio.simulate("change", {target: {checked: true}});
expect(onSortSpy.called).to.equal(true);
expect(onSortSpy.calledWith("none")).to.equal(true);

chai-enzyme

// class name
expect(wrapper.find('span')).to.have.className('child');

// contains a given node
expect(wrapper).to.contain(<User index={1} />);

// value, checked, disabled, selected
expect(wrapper.find('#checked')).to.be.checked();
expect(wrapper.find('input')).to.have.value('test');

// contains the text
expect(wrapper.find('.msg')).to.not.have.text('Hello world');

// check for the correct style
expect(wrapper).to.have.style("width", WIDTH + "px");

// attr, data
<span id='msg' data-name='child'>test</span>

expect(wrapper).to.have.attr('id', 'msg');
expect(wrapper).to.have.data('name', 'child');

// prop, props
<User index={1} user={{name: 'Jane'}} />

expect(wrapper).to.have.props([ 'index', 'user' ]);

Unit testing in React

By kenjiru

Unit testing in React

What and how to unit test.

  • 378