Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Shallow Rendering Jest Snapshots

I am just starting with Jest and Snapshot testing and I was wondering why all examples do "deep rendering" of React components to create snapshots.

Example

const A = () => {
   return <div><B /><B /></div>
}
const B = () => {
   return <div>This is B</div>
}

// TEST
describe('Test', () => {

   it('renders correctly', () => {
      const tree = ReactTestRenderer.create(
         <A />
      ).toJSON();

      expect(tree).toMatchSnapshot();
   });
});

Snapshot:

exports[`Summary DOM rendering renders correctly 1`] = `
<div>
  <div>
     This is B
  </div>
  <div>
     This is B
  </div>
</div>
`;

While this is useful sometimes I think it makes far more sense to have separate tests/snapshots for A and B and to do shallow rendering so if I change B my A snapshots do not need to be updated. So I want my snapshots to look like this:

exports[`Summary DOM rendering renders correctly 1`] = `
<div>
  <B />
  <B />
</div>
`;

Is there any way to do this? Is this a good idea in the first place? If it is possible why is shallow rendering not the preferred way in the docs?

like image 642
Hoffmann Avatar asked Feb 20 '17 15:02

Hoffmann


People also ask

Should you use Jest snapshots?

Snapshot tests are a very useful tool whenever you want to make sure your UI does not change unexpectedly. A typical snapshot test case renders a UI component, takes a snapshot, then compares it to a reference snapshot file stored alongside the test.

How do I view Jest snapshots?

To review your snapshots, run npm run jest-html ( yarn run jest-html ). This launches your default browser and opens the jest-html application. By default, jest-html looks for snapshots under **/*. snap,!

Does shallow render child components?

If you test a component using shallow rendering you're not guaranteeing that the component is actually rendering correctly e.g. if any child components are broken, it won't cause the test to fail.


2 Answers

Update(Jan 3, 2018)

Shallowrender has been moved to react-test-renderer

import ShallowRenderer from 'react-test-renderer/shallow'

it('Matches snapshot', () => {
  const renderer = new ShallowRenderer()
  const result = renderer.render(<A />)
  expect(result).toMatchSnapshot()
})

You can use react-test-utils Shallow Rendering with snapshot testing as well:

import ReactTestUtils from 'react-addons-test-utils';

describe('Test', () => {

   it('renders correctly', () => {
      const renderer = ReactTestUtils.createRenderer();
      expect(renderer.render(<A />)).toMatchSnapshot();
   });
});

With that you can create renderer that only renders 1 level deep, that is: it'll only render what's in your component's render() function, and not render child components.

react-test-renderer is a different renderer, it renders your component (and the whole tree) to JSON. Currently it has no option to shallow render, it will work just like in the browser and render everything, but to JSON.

They both are good for testing because they don't require a DOM environment and they have different characteristics. You can choose one that suits better your use case.

like image 173
Lucas Avatar answered Oct 24 '22 06:10

Lucas


You can use enzyme to shallow-render your components.

I can't tell you for sure as to why it's not the preferred method in the docs, but my guess would be that it's because the functionality isn't built into the official react-test-renderer.

like image 38
Andy_D Avatar answered Oct 24 '22 06:10

Andy_D