Testing React Native components with Enzyme

Testing React Native components has a reputation. A bad one. But if you watch this great talk by Leland Richardson I think you’ll agree that things have changed.

Leland Richardson put a ton of work into making his testing utility, Enzyme, compatible with React Native by having “painstakingly mocked out the entire React Native API”. The result of this massive effort is painless testing of React Native components. Truly great stuff.

If this all sounds fantastic and you’d like to dive into a fresh project with enzyme already configured - I recommend checking out the React Native/Enzyme example repository.

If you have an existing project that you’d like to start testing with enzyme you can follow along below.

Testing an existing project

To start, we’ll install enzyme, chai, and mocha.

npm install enzyme chai mocha --save-dev

We also need to install the result of Leland Richardson’s hard work as mentioned above - the react-native-mock library.

npm install react-native-mock --save-dev

Enzyme requires a custom babel configuration, so we’ll install babel-core.

npm install babel-core --save-dev

Add an empty .babelrc file to your root directory, we’ll define a preset here in a moment.

After adding a .babelrc file to your project the packager will ignore React Native’s default babel configuration in preference for your custom one. If we want to maintain those defaults we are in luck - there’s a preset for that!

npm install babel-preset-react-native -save-dev

Let’s add this preset to our .babelrc file.

{
"presets": [
"react-native"
]
}

Finally we’ll install react, react-dom, and react-addons-test-utils.

npm install react react-dom react-addons-test-utils --save-dev

Create a “test” folder in your root directory and in that folder create a file called MyComponent.js with the following.

import React, { View, Text, StyleSheet } from 'react-native';
import { shallow } from 'enzyme';
import { expect } from 'chai';
const Test = React.createClass({
render() {
return (
<View>
<Text>enzyme</Text>
<Text>rules</Text>
</View>
)
}
});
describe('<Test />', () => {
it('it should render 1 view component', () => {
const wrapper = shallow(<Test/>);
expect(wrapper.find(View)).to.have.length(1);
});

it('it should render 2 text components', () => {
const wrapper = shallow(<Test/>);
expect(wrapper.find(Text)).to.have.length(2);
});
});

To run our tests we’ll add a “test” script to our package.json file.

"scripts": {
"start": "node node_modules/react-native/local-cli/cli.js start",
"test": "mocha --require react-native-mock/mock.js —-compilers js:babel-core/register --recursive test/*.js"
}

Run the test in your terminal with:

npm test

That’s it! Go ahead and import some of your existing components and play around with some tests. Be sure to check out the enzyme documentation.

References

https://www.youtube.com/watch?v=V5N0Ukb8LGg
https://github.com/airbnb/enzyme
https://github.com/lelandrichardson/enzyme-example-react-native
https://github.com/airbnb/babel-preset-airbnb
https://github.com/lelandrichardson/react-native-mock
https://github.com/facebook/react-native/blob/e6cb02d61af82832016bafb259a1b0d3039a357e/babel-preset/README.md