Enzyme Testing
Valerie Kraucunas

What i'll be covering
- Intro to Enzyme
- Rendering Methods
- Best Practices
- Upcoming Features of Enzyme
Please ask questions as they come to you.
If you have a better answer than I do, please contribute.
INTRO TO ENZYME
Started by Airbnb engineer Leland Richardson, since open sourced
Enzyme is a JavaScript Testing utility for React that makes it easier to assert, manipulate, and traverse your React Components' output.

INTRO TO ENZYME
Benefits of using Enzyme
- Unopinionated
- jQuery style DOM traversal
- Mocking out components to test is clean
Enzyme makes asking questions about the rendered output of your React components easy and intuitive by providing a fluent interface around rendered React components.
INTRO TO ENZYME
So uh... what am I supposed to be testing?
- Is it a valid component?
- Is everything rendering that you're expecting?
- Checking props
- Simulating events, such as a click
INTRO TO ENZYME
Getting Started
npm i --save-dev enzyme
npm i --save-dev react-addons-test-utils
npm i --save-dev react-domnpm i --save-dev chai-enzyme
npm i --save-dev jasmine-enzyme
npm i --save-dev jest-enzyme
npm i --save-dev should-enzymeOptional Assertion Libraries

*
INTRO TO ENZYME
Example of basic test
import React from 'react';
import { shallow } from 'enzyme';
import ToDoList from '../components/ToDoList';
import ToDoItem from '../components/ToDoItem';
describe('<ToDoList />', () => {
it('renders the entire list of items', () => {
const items = [mockItem(), mockItem() /*, ... */];
const wrapper = shallow(<ToDoList items={items} />);
expect(wrapper.find(ToDoList)).to.have.length(items.length);
});
});INTRO TO ENZYME
Example of complex test
import React from 'react';
import { shallow } from 'enzyme';
import chai, {expect} from 'chai';
import { stub } from 'sinon';
import sinonChai from 'sinon-chai';
chai.use(sinonChai);
const FBButton4 = ({ likePage }) => {
const onClick = () => {
if (FB.like()) {
likePage();
}
};
return <button onClick={onClick}>Like this on Fakebook!</button>;
};
describe('<FBButton4 />', () => {
it('will call our action because FB.like returns `true`', () => {
const likePage = stub();
const wrapper = shallow(<FBButton4 likePage={likePage} />);
stub(FB, 'like').returns(true);
wrapper.find('button').simulate('click');
expect(likePage).to.have.been.called;
FB.like.restore(); // This is important!
});
});Rendering methods
Shallow
Mount
Render

Rendering methods
Shallow
Purest unit testing option
No children rendered, to ensure that your tests aren't indirectly asserting on behavior of child components.
Fastest rendering method, works best on stateless components

Rendering methods
Mount

Full DOM rendering, including children
If you do not want to run your tests inside of a browser, the recommended approach to using mount is to depend on a library called jsdom which is essentially a headless browser implemented completely in JS.
Includes the most lifecycle testing
Rendering methods
Render
Renders static html, including children, fewest lifecycle methods covered
Uses Cheerio
Render is useful when you just want to assert on the DOM your component(s) render, lets you get around incorporating jsdom for mount

Best practices
- Start with .shallow()
- Always refresh your wrapper variable between tests
- Only pass wrappers the required props for component to render
- If you're having trouble writing a test for an existing component, consider rewriting the component to make it more testable
- Pick an assertion syntax and stick to it
Best practices
What about React Native?
npm i --save-dev react-native-mock
// test script in package.json
mocha --require react-native-mock/mock --recursive path/to/test/dir
React Native has many environmental dependencies that can be hard to simulate without a host device.
Best practices
Test double library!
npm i --save-dev sinonAllows you to replace the difficult parts of your tests with something that makes testing simple.
Best practices
Test double library!
- Spies, which offer information about function calls, without affecting their behavior
- Stubs, which are like spies, but completely replace the function. This makes it possible to make a stubbed function do whatever you like — throw an exception, return a specific value, etc
- Mocks, which make replacing whole objects easier by combining both spies and stubs
Future of enzyme
- Integration tests
- Improved CSS Selector Support
- Improve event simulation
- React Native testing improvements

Thank you!
Valerie Kraucunas
valeriekraucunas@gmail.com
vkraucunas


RESOURCES
Enzyme Testing
By Valerie Kraucunas
Enzyme Testing
"Untested code is broken code." Enzyme, the testing utility for React, is flexible, intuitive, and compatible with most test runners. When matched with a test double library like Sinon.js, Enzyme becomes capable of unit testing both components and reducers. Together we'll cover the tradeoffs of the different rendering methods provided from Enzyme, best practices for writing test files, and upcoming features of Enzyme. (ReactJS 2/2017)
- 861