简体   繁体   中英

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?

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.

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 .

Shallow rendering is preferred for unit tests, where only a single component is being tested. In your question, shallow rendering the <A/> component is the correct approach. The it('renders correctly') test should only check that <A/> renders a certain way. That test should not depend on how <B/> renders.

To test more complex behaviors that involve multiple components, mount or render can be used. This allows for testing aspects of <A/> and <B/> .

(I use enzyme for test rendering.)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM