URL: https://www.progressiverobot.com/react-react-snapshot-testing/

[Snapshot testing](/testing/snapshot-testing-jest/) is particularly useful in testing React components. Let's see how it's done.

react-test-renderer

react illustration for: react-test-renderer

You need to render your React components before you serialize them. Be sure to install react-test-renderer so you can do so.

				
					
yarn add --dev react-test-renderer

				
			

Creating a Snapshot for a Component

Let's say you have a component that pages a person when you click a button

				
					
// Pager.js

import React from 'react';



export default function Pager({ name }) {

  const onClickCallback = () => alert(`Paging ${name}!`);

  return (

    <div>

      <h1>{name}</h1>

      <button onClick={onClickCallback}>Page</button>

    </div>

  );

}

				
			

Your test should look something like

				
					
// Pager.test.js

import React from 'react';

import renderer from 'react-test-renderer';



import Pager from './Pager';



it('looks okay.', () => {

  const name = 'John';

  // Render the component with the props.

  const tree = renderer.create(<Pager name={name}/>)

  // Convert it to JSON.

    .toJSON();

  // And compare it to the snapshot.

  expect(tree).toMatchSnapshot();

});

				
			

The snapshot goes to the __snapshots__ folder and all subsequent test runs will compare to that. From there you can edit Pager as you please; so long as the same props give the same result, the snapshot will match. But that's also a problem.

Snapshots Are Not a Magic Bullet

It's important to note that, while objects are serializable, functions (and therefore callbacks) are not. If you open up Pager.test.js.snap, you'll see that onClickCallback is being represented as [Function].

				
					
// Jest Snapshot v1, https://goo.gl/fbAQLP



exports[`properly writes name. 1`] = `

<div>

  <h1>

    John

  </h1>

  <button

    onClick={[Function]}

  >

    Page

  </button>

</div>

`;

				
			

If Pager is rewritten so that onClickCallback does something else, the snapshot will still pass.

				
					
export default function Pager({ name }) {

  // Not what you want it to do, but it will still pass.

  const onClickCallback = () => alert(`Paging {name}!`);

  return (

    <div>

      <h1>{name}</h1>

      <button onClick={onClickCallback}>Page</button>

    </div>

  );

}