At the previous part of the tutorial, we’ve briefly covered the basics of unit testing. This time we will go further and start testing React with the Enzyme library. Thanks to the that, your application will be more reliable and it will be easier to avoid regression. Even though we will be using Jest here, Enzyme also works with libraries like Mocha and Chai.
JavaScript testing tutorial: the basics of Enzyme
Enzyme is a library for manipulating your React components while testing. It was developed by the company Airbnb.
Setting up Enzyme
I will go ahead and assume that you have Jest already working. If not, feel free to take a look at the previous part of the course. Let’s start with installing Enzyme
npm install enzyme
The first thing you will need to do is to create a
setupTests.js
file. It will contain the usage of an
adapter which is an additional library that allows you to use Enzyme with a specific set of
React versions. I will use
React 16.x, therefore I will install
enzyme-adapter-react-16. For a compatibility table check out the Enzyme repo.
You can also find adapters to libraries like preact and inferno
npm install enzyme-adapter-react-16
Once you have this sorted out, the content of your
setupTests.js
file should look like that:
setupTests.js
import { configure } from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
configure({adapter: new Adapter()});
The last thing to do is to provide a path to this file in the package.json
package.json
"jest": {
"setupTestFrameworkScriptFile": "<rootDir>/app/setupTests.js"
}
And there you go, you’re all set!
Shallow rendering
The most basic usage of the Enzyme library is the shallow rendering. It allows you to render only the parent component without its children. It makes the shallow rendering not only fast but also great for unit testing. This way you won’t be testing any other components that the one that you pass to the shallow function.
App.js
import React from 'react';
const App = () => {
return <h1>Hello world!</h1>
}
export default App;
App.test.js
import React from 'react';
import { shallow } from 'enzyme';
import App from './App';
describe('app component', () => {
it('contains a header with the "Hello world!"', () => {
const app = shallow(<App/>);
expect(app.containsMatchingElement(<h1>Hello world!</h1>)).toEqual(true);
});
});
In our simple test, we are checking if the
App component contains a certain header. After running
npm run test
you will see a success message.
PASS app/App.test.js
app component
✓ contains a header with the "Hello world!"
A very important thing to remember here is that even though we are using Enzyme, our test runner is still Jest. Since we are using the expect function, you have access to a wide variety of matcher functions, that you can call. We’ve mentioned them in the first part of the course. For a list, visit the Jest documentation.
Let’s create a bit more interesting tests. To do that, we will create a brand new component.
ToDoList.js
import React from 'react';
const ToDoList = (props) => {
return (
<ul>
{
props.tasks.map((taskName, index) =>
<li key={index}>{taskName}</li>
)
}
</ul>
)
};
export default ToDoList;
Let’s test what happens if the provided list of tasks is empty, and what happens if it contains tasks.
ToDoList.test.js
import React from 'react';
import { shallow } from 'enzyme';
import ToDoList from './ToDoList';
describe('ToDoList component', () => {
describe('when provided with an empty array of tasks', () => {
it('contains an empty <ul> element', () => {
const toDoList = shallow(<ToDoList tasks={[]}/>);
expect(toDoList).toContainReact(<ul/>);
})
it('does not contain any <li> elements', () => {
const toDoList = shallow(<ToDoList tasks={[]}/>);
expect(toDoList.find('li').length).toEqual(0);
})
});
describe('when provided with an array of tasks', () => {
it('contains a matching number of <li> elements', () => {
const tasks = ['Wash the dishes', 'Make the bed'];
const toDoList = shallow(<ToDoList tasks={tasks}/>);
expect(toDoList.find('li').length).toEqual(tasks.length);
})
});
});
The tests pass without problems, but we should explain a few things introduced here.
In the first test, we’ve used a
toContainReact
function, which is a custom matcher function. It is a part of the
enzyme-matchers library. To use it with
Jest, install
jest-enzyme package.
npm install jest-enzyme
The last thing to do is to import it in our setupTests file.
setupTests.js
import { configure } from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
import 'jest-enzyme';
configure({adapter: new Adapter()});
For a list of function it provides, check out the readme. You might find it useful.
In the second test, we’ve called a
find
function on our component. This is thanks to the fact that the
shallow
function returns the
ShallowWrapper, which is a wrapper around the rendered output. It has a set of functions that you can call on it. To check the list go to the
Enzyme documentation.
Running all our tests gives us a success message!
PASS app/App.test.js
PASS app/components/ToDoList/ToDoList.test.js
Test Suites: 2 passed, 2 total
Tests: 4 passed, 4 total
Snapshots: 0 total
Time: 1.41s
Ran all test suites.
Summary
Today we’ve learned the very basics of testing React components with Enzyme. We’ve covered installing Enzyme and running our first, simple tests. The type of rendering that we’ve used is called shallow rendering. It is called like that because it does not render any child components. It works very well when writing unit tests. In the upcoming parts of the tutorial, we will cover other types of rendering and learn how to test many different parts of our application. It will include techniques like snapshot testing and mocking data. See you next time!
The post JavaScript testing tutorial – part two. Introducing Enzyme and testing React components appeared first on Marcin Wanago Blog - JavaScript, both frontend and backend.