Testing React Native components with Enzyme
Testing React Native components has a reputation. A bad one.
Now, if you watch this great talk by Leland Richardson I think you’ll agree that the reputation of React Native testing may 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