Snapshot Tests in React Using Jest

Published Mar 30, 2018Last updated Apr 24, 2018
Snapshot Tests in React Using Jest

Writing tests might not have been the most enjoyable thing for you in the past but I for sure hope that after reading this article, you'll be able to increase the test coverage.

Today, I am going to talk about snapshot tests using Jest. They're easy to write, they're fast, and most importantly, you'll for sure know if something is not right if you use them correctly. These snapshots will warn you for every change you make that affects the rendering: whether you're doing something simple, or more advanced rendering that includes conditions or looping.

Configure Jest

First, you need to set up Jest in the project. For that, install a few packages:

npm install --save-dev jest babel-jest babel-core regenerator-runtime babel-preset-es2015 babel-preset-react 

You don't need to install regenerator-runtime if you use npm 3 or 4 or Yarn.
You'll have to add .babelrc file in project root next:

{
  "presets": ["env", "es2015", "react"]
}

Also, you need to install react-test-renderer package. This package is used to render React components to pure JavaScript objects.

npm i react-test-renderer --save

If you need some specific configuration for your tests, you can configure Jest using package.json file.

You're now ready to write your first snapshot test!

Writing snapshot tests

When writing snapshot tests using Jest, you should basically just follow the next template:

import renderer from 'react-test-renderer';
import Component from '../Component.react';

it('renders correctly', () => {
  const tree = renderer.create(
    <Component 
        prop={propValue}
    />
  ).toJSON();
  expect(tree).toMatchSnapshot();
});

You use react-test-renderer to create a component with desired props, transform it to JSON and then check if it matches a snapshot. Easy, right?

Here's a more concrete example — let's say you have a dummy component called Input, for which you want to write a snapshot test:

function Input({ id, placeholder, label, onChange, value }) {
    return (
        <div>
            <label htmlFor={id} >
                { label }
            </label>
            <input
                id={id}
                placeholder={placeholder}
                onChange={onChange}
                value={value}
            />
        </div>
    )
}

For the Input component, it can look something like this:

import renderer from 'react-test-renderer';
import Input from '../Input.react';

it('renders correctly', () => {
  const tree = renderer.create(
    <Input 
        id={'id'}
        label={'label'}
        placeholder={'Placeholder'}
        onChange={() => {}}
        value={''}
    />
  ).toJSON();
  expect(tree).toMatchSnapshot();
});

Running tests

To run the test, you just need to type jest command in terminal. Output snapshot file will be created, and when running the test next time, Jest will compare that output snapshot file to your updated component.

If you make some changes to a component that affects its rendering, (for example, adding a new item to the list to be mapped), the test will fail because the new object will be different from previous one. If changes were intended, you can update snapshot using the command jest --updateSnapshot.

Keep in mind that all of these output snapshot files should be committed alongside the modules they are covering and their tests, as they are part of the test.

Of course, while your snapshot tests cover things like if conditional rendering is working properly, they don't test whether clicking on that link will properly redirect to another page. You will still need to write tests that check if the functionality works as expected, but those I'll be covering in some future article.

Thank you for taking the time to read this article! I hope you find it helpful.

This article was originally pubslihed on Kolosek Blog.

Discover and read more posts from Mark_S
get started