- 1. JavaScript testing #1. Explaining types of tests. Basics of unit testing with Jest
- 2. JavaScript testing #2. Introducing Enzyme and testing React components
- 3. JavaScript testing #3. Testing props, the mount function and snapshot tests.
- 4. JavaScript testing #4. Mocking API calls and simulating React components interactions
- 5. JavaScript testing #5. Testing hooks with react-hooks-testing-library and Redux
- 6. JavaScript testing #6. Introduction to End-to-End testing with Cypress
- 7. JavaScript testing #7. Diving deeper into commands and selectors in Cypress
- 8. JavaScript testing #8. Integrating Cypress with Cucumber and Gherkin
- 9. JavaScript testing #9. Replacing Enzyme with React Testing Library
- 10. JavaScript testing #10. Advanced mocking with Jest and React Testing Library
- 11. JavaScript testing #11. Spying on functions. Pitfalls of not resetting Jest mocks
- 12. JavaScript testing #12. Testing downloaded files and file inputs with Cypress
- 13. JavaScript testing #13. Mocking a REST API with the Mock Service Worker
- 14. JavaScript testing #14. Mocking WebSockets using the mock-socket library
- 15. JavaScript testing #15. Interpreting the code coverage metric
- 16. JavaScript testing #16. Snapshot testing with React, Jest, and Vitest
- 17. JavaScript testing #17. Introduction to End-to-End testing with Playwright
- 18. JavaScript testing #18. E2E Playwright tests for uploading and downloading files
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
1 |
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
1 |
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
1 2 3 4 |
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
1 2 3 |
"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
1 2 3 4 5 6 7 |
import React from 'react'; const App = () => { return <h1>Hello world!</h1> } export default App; |
App.test.js
1 2 3 4 5 6 7 8 9 10 |
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.
1 2 3 |
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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
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.
1 |
npm install jest-enzyme |
The last thing to do is to import it in our setupTests file.
setupTests.js
1 2 3 4 5 |
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!
1 2 3 4 5 6 7 8 |
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!