Testing React components with Jest and Enzyme
August 2019: This article is out of date, check my new article about testing React components with Jest and Enzyme.
October 2017: the article was updated to React 16 and Enzyme 3.
Some people say that testing React components is useless and in many cases it is, but there are a few cases when I think it’s useful:
- component libraries,
- open source projects,
- integration with third-party components,
- bugs, to prevent regressions.
I’ve tried many tools and finally have found a combination that I like enough to suggest to other developers:
- Jest, a test runner;
- Enzyme, a testing utility for React;
- enzyme-to-json to convert Enzyme wrappers for Jest snapshot matcher.
For the most of my tests I use shallow rendering with Jest snapshots.
Shallow rendering renders only component itself without its children. So if you change something in a child component it won’t change shallow output of your component. Or a bug, introduced to a child component, won’t break your component’s test. It also doesn’t require DOM.
For example this component:
Will be rendered by React like this:
But like this with shallow rendering:
Note that the
Icon component was not rendered.
Jest snapshots are like those old text UIs with windows and buttons made of text characters: it’s a rendered output of your component stored in a text file.
You tell Jest that you want to be sure that output of this component should never change accidentally and Jest saves it to a file that looks like this:
Every time you change your markup Jest will show you a diff and ask you to update a snapshot if the change was intended.
Jest stores snapshots besides your tests in files like
__snapshots__/Label.spec.js.snap and you need to commit them with your code.
- Very fast.
- Snapshot testing.
- Awesome interactive watch mode that reruns only tests that are relevant to your changes.
- Helpful fail messages.
- Simple configuration.
- Mocks and spies.
- Coverage report with a single command line switch.
- Active development.
- Impossible to write silently wrong asserts like
expect(foo).to.be.a('function')in Chai because it’s the only natural thing to write after (correct)
- Convenient utilities to work with shallow rendering, static rendered markup or DOM rendering.
- jQuery-like API to find elements, read props, etc.
First install all the dependencies including peer dependencies:
snapshotSerializers allows you to pass Enzyme wrappers directly to Jest’s snapshot matcher, without converting them manually by calling enzyme-to-json’s
test/jestsetup.js file to customize Jest environment (see
For CSS Modules also add to
jest section in your
npm install --save-dev identity-obj-proxy.
Note that identity-obj-proxy requires
node --harmony-proxies flag for Node 4 and 5.
Testing basic component rendering
That’s enough for most non-interactive components:
Sometimes you want to be more explicit and see real values in tests. In that case use Enzyme API with regular Jest assertions:
In some cases you just can’t use snapshots. For example if you have random IDs or something like that:
You can simulate an event like
change and then compare component to a snapshot:
Sometimes you want to interact with an element in a child component to test effect in your component. For that you need a proper DOM rendering with Enzyme’s
Testing event handlers
Similar to events testing but instead of testing component’s rendered output with a snapshot use Jest’s mock function to test an event handler itself:
Not only JSX
Jest snapshots work with JSON so you can test any function that returns JSON the same way you test your components:
Debugging and troubleshooting
Debugging shallow renderer output
debug method to print shallow renderer’s output:
Failing tests with enabled coverage
When your tests fail with
--coverage flag with diff like this:
Try to replace arrow function component with regular function:
You may see an error like this when you run your tests:
Warning: React depends on requestAnimationFrame. Make sure that you load a polyfill in older browsers. http://fb.me/react-polyfills
- Jest cheat sheet
- Testing React Applications by Max Stoiber
- Migrating to Jest by Kent C. Dodds
- Migrating AVA to Jest by Jason Brown