Test Your Way to a Better Sleep

Unit test your react components
and finally get a full nights sleep!

by Jared Schaab
@JaredSchaabjared.schaab@gmail.com

Sleep Tip #1

Write Unit Tests

  • Documentation for new developers
  • Degree of confidence that functionality is correct
  • Baseline functionality for when refactoring
  • Reduce number of bugs
  • Validate bugs are fixed…and not broken again later

Sleep Tip #2

Make Sure They Don't Suck

Readable

describe('add()', () => {
    it('should add stuffs', () => {
        expect(add(1, 2)).toEqual(3);
        expect(add(0, 0)).toEqual(0);
        expect(add(-1, 2)).toEqual(1);
        expect(add(-1, -2)).toEqual(-3);
        expect(add(1, 2, 5)).toEqual(3);

    });
});
describe('add()', () => {
    it('should add two positive numbers', () => {
        expect(add(1, 2)).toEqual(3);
    });

    it('should add zeros', () => {
        expect(add(0, 0)).toEqual(0);
    });

    it('should add a negative and a positive value', () => {
        expect(add(-1, 2)).toEqual(1);
        expect(add(1, -2)).toEqual(-1);
    });
});

Trustworthy

describe('add()', () => {
    it('should add two positive numbers', () => {
        expect(3).toEqual(3);
    });
});

Maintainable

Sleep Tip #3

Organize

actions/
    CommandActions.js
    CommandActions.spec.js
    UserActions.js
    UserActions.spec.js
    ...
components/
    Header.js
    Header.spec.js
    Sidebar.js
    Sidebar.spec.js
    ...
containers/
    App.js
    App.spec.js
    Command.js
    Command.spec.js
    ...
reducers/
    index.js
    index.spec.js
    command.js
    command.spec.js
    ...

AWESOME!!

So now what?

Tools of the Trade

What sort of tools will we need?

  • Test Runner (mocha, jest, karma)
  • Babel
  • React test helper (enzyme)
  • Mocking library (rewire, sinon)

Mocha and Chai

describe('Thing under test', function() {
    it('should add some things', function() {
        expect(add(1, 2)).to.equal(3);
    });
});

Babel

import { shallow } from 'enzyme';

// note ES2015 arrow function and JSX
// not currently supported with node
it('should have some things', () => {
    const wrapper = shallow(<WickedAwesomeComponent />);
    expect(wrapper.find('.class')).to.have.length(3);
});

Enzyme

More info at the Enzyme github repo

shallow

import { shallow } from 'enzyme';

it('should have some things', () => {
    const wrapper = shallow(<WickedAwesomeComponent />);
    expect(wrapper.find('.class')).to.have.length(3);
});

mount

import { mount } from 'enzyme';
import sinon from 'sinon';

it('calls componentDidMount', () => {
    spy(WickedAwesomeComponent.prototype, 'componentDidMount');
    const wrapper = mount(<WickedAwesomeComponent />);
    expect(WickedAwesomeComponent.prototype.componentDidMount.calledOnce)
        .to.equal(true);
});

render

import { render } from 'enzyme';

it('has words', () => {
    // assuming the WickedAwesomeComponent renders <div>{ words }<div/>
    var wrapper = render(<WickedAwesomeComponent words="some words here" />);
    expect(wrapper.text()).to.contain('some words here');
});