Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Difference between Shallow, Mount and render of Enzyme

Shallow

Real unit test (isolation, no children render)

Simple shallow

Calls:

  • constructor
  • render

Shallow + setProps

Calls:

  • componentWillReceiveProps
  • shouldComponentUpdate
  • componentWillUpdate
  • render

Shallow + unmount

Calls:

  • componentWillUnmount

Mount

The only way to test componentDidMount and componentDidUpdate. Full rendering including child components. Requires a DOM (jsdom, domino). More constly in execution time. If react is included before JSDOM, it can require some tricks:

require('fbjs/lib/ExecutionEnvironment').canUseDOM = true;

Simple mount

Calls:

  • constructor
  • render
  • componentDidMount

Mount + setProps

Calls:

  • componentWillReceiveProps
  • shouldComponentUpdate
  • componentWillUpdate
  • render
  • componentDidUpdate

Mount + unmount

Calls:

  • componentWillUnmount

Render

only calls render but renders all children.

So my rule of thumbs is:

  • Always begin with shallow
  • If componentDidMount or componentDidUpdate should be tested, use mount
  • If you want to test component lifecycle and children behavior, use mount
  • If you want to test children rendering with less overhead than mount and you are not interested in lifecycle methods, use render

There seems to be a very tiny use case for render. I like it because it seems snappier than requiring jsdom but as @ljharb said, we cannot really test React internals with this.

I wonder if it would be possible to emulate lifecycle methods with the render method just like shallow ? I would really appreciate if you could give me the use cases you have for render internally or what use cases you have seen in the wild.

I'm also curious to know why shallow does not call componentDidUpdate.

Kudos goes to https://github.com/airbnb/enzyme/issues/465#issuecomment-227697726 this gist is basically a copy of the comment but I wanted to separate it from there as it includes a lot of general Enzyme information which is missing in the docs.

@YashodharPalkuru

This comment has been minimized.

Copy link

commented Jan 4, 2018

I think i got it. Good one, Thanks

@anushshukla

This comment has been minimized.

Copy link

commented Jan 6, 2018

just the explanation, I was looking for. Thank you!

@c1aphas

This comment has been minimized.

Copy link

commented Jan 17, 2018

As of Enzyme v3, the shallow API does call React lifecycle methods such as componentDidMount and componentDidUpdate. (https://github.com/airbnb/enzyme/blob/master/docs/api/shallow.md)
So this part about mount method: "only way to test componentDidMount and componentDidUpdate." isn't correct now.

@iprignano

This comment has been minimized.

Copy link

commented Jan 17, 2018

@c1aphas Thanks for pointing that out, super useful!

@FLoppix

This comment has been minimized.

Copy link

commented Mar 7, 2018

❤️

@Julian-Jurai

This comment has been minimized.

Copy link

commented Mar 8, 2018

Great break down!

@xploreraj

This comment has been minimized.

Copy link

commented Mar 20, 2018

Was thinking same, but having someone else document it just increases the confidence. 🎉

@citypaul

This comment has been minimized.

Copy link

commented Mar 21, 2018

I prefer to go the opposite way - almost never use shallow ;-)

@JoeDuncko

This comment has been minimized.

Copy link

commented May 20, 2018

Thanks!

@99M8

This comment has been minimized.

Copy link

commented Jun 3, 2018

Awesome! Thanks a lot, man! 👍

@elboletaire

This comment has been minimized.

Copy link

commented Jun 12, 2018

Using enzyme 3.3.0, using shallow executes componentDidMount, so... apparently there's something wrong in this explaining.

Edit: I think it's related to the setProps, but I'm not sure... is the same using wrapper.setProps than specifying the props to the component? Does anyone know if enzyme internally calls setProps too? If so, I guess that this two examples should execute componentDidMount:

const props = {whatever: 'test'}
const wrapper = shallow(<MyComponent {...props} />)

const wrapper = mount(<MyComponent {...props} />)

If enzyme, internally, uses setProps to set the props to the component.. I guess both examples should run componentDidMount.

Can anyone correct me please?

@Andruschenko

This comment has been minimized.

Copy link

commented Jun 14, 2018

@elboletaire I also noticed that shallow is indeed calling componentDidMount. I would also like to know why..

@datenreisender

This comment has been minimized.

Copy link

commented Jun 18, 2018

@Andruschenko @elboletaire That behaviour was changed in Enzyme 3, https://github.com/airbnb/enzyme/blob/master/docs/guides/migration-from-2-to-3.md#lifecycle-methods so the information in this gist is slightly outdated.

@fokusferit

This comment has been minimized.

Copy link
Owner Author

commented Jun 21, 2018

It's really interesting how this Gist from 2017 still creates value to people! I will sit down and update this soon, thanks to @elboletaire and @datenreisender.

@PhilTheAir

This comment has been minimized.

Copy link

commented Jul 5, 2018

❤️

@alisonjonck

This comment has been minimized.

Copy link

commented Aug 16, 2018

<3

@kangisworking

This comment has been minimized.

Copy link

commented Aug 28, 2018

Thanks a lot!! really helped. 👍

@StanleySathler

This comment has been minimized.

Copy link

commented Aug 29, 2018

Thanks a lot, @fokusferit. That really helped. 👍

@oonsamyi

This comment has been minimized.

Copy link

commented Sep 5, 2018

I published gist with more actual information (for react 16.4) - https://gist.github.com/oonsamyi/2422357b4e68a4461dcd11b7724291eb.
Can somebody check my corrections? Grammar corrections are also welcome.

@juanbarman

This comment has been minimized.

Copy link

commented Sep 5, 2018

Simple and Clean. 👍

@guiqui

This comment has been minimized.

Copy link

commented Sep 5, 2018

Hey this is great, really helpful!

@giwiro

This comment has been minimized.

Copy link

commented Sep 12, 2018

Thanks ❤️

@thanhluand

This comment has been minimized.

Copy link

commented Oct 4, 2018

This is great, really helpful. 👍

@Gikoskos

This comment has been minimized.

Copy link

commented Oct 11, 2018

A legend and a scholar

@einarpersson

This comment has been minimized.

Copy link

commented Oct 12, 2018

@fokusferit
This is not up to date.

As of Enzyme v3, the shallow API does call React lifecycle methods such as componentDidMount and componentDidUpdate

Official docs

@maxstralka

This comment has been minimized.

Copy link

commented Nov 12, 2018

Thanks so much for this!

@knownasdee

This comment has been minimized.

Copy link

commented Nov 28, 2018

thank you!

@victor-dantas

This comment has been minimized.

Copy link

commented Nov 28, 2018

Thanks so much! {:

@sixertoy

This comment has been minimized.

Copy link

commented Nov 29, 2018

Peerfect 👍

@gustafsilva

This comment has been minimized.

Copy link

commented Dec 18, 2018

Thanks 👍

@Shrikant9

This comment has been minimized.

Copy link

commented Dec 21, 2018

Thanks, this stopped a big fight at my work.

@iwisunny

This comment has been minimized.

Copy link

commented Jan 15, 2019

thx 👍

@grzennio

This comment has been minimized.

Copy link

commented Jan 21, 2019

@fokusferit you should definatelly update this!
But thanks a lot.

@ycjcl868

This comment has been minimized.

Copy link

commented Feb 19, 2019

emmm, What's the difference between shallow and mount?

@OzzyTheGiant

This comment has been minimized.

Copy link

commented Feb 19, 2019

@ycjcl868
TL;DR:
Shallow: create and test component only (no children)
Mount: same as shallow but mounts with children and parent/host component, allows lifecycle methods
Render: outputs the html given by the component, including children

For those of you coming or familiar with Angular testing, Shallow is basically just testing the component while providing 'stub' children component in the TestingModule, if necessary. Mount would be the same but instead providing the real children components in the TestingModule. Render would be basically using the fixture.debugElement.query(By.css("") feature.

@fokusferit

This comment has been minimized.

Copy link
Owner Author

commented Mar 4, 2019

Sorry everyone, this gist is still creating value for people, so I will allocate time this week, to get it updated for v3 of Enzyme. Especially as of React 15 (I think) many lifecycle methods are deprecated, so shallow and mount definitely behave different.

@yuliangjin1985

This comment has been minimized.

Copy link

commented Mar 11, 2019

Helpful. Just started to work on react and enzyme.

@LBWright

This comment has been minimized.

Copy link

commented Mar 11, 2019

@fokusferit as of Enzyme v3, Shallow supports CDM and CDU. I see your comment above, I do think it's worth mentioning, however.

@DKNY1201

This comment has been minimized.

Copy link

commented Mar 26, 2019

Good to know. Please keep it up to date. Thank you.

@misingnoglic

This comment has been minimized.

Copy link

commented Apr 2, 2019

Thank you!

@cythilya

This comment has been minimized.

Copy link

commented May 2, 2019

Thanks for sharing!

@kleva-j

This comment has been minimized.

Copy link

commented May 4, 2019

Really helpful. Thanks

@Seolhun

This comment has been minimized.

Copy link

commented May 8, 2019

Really good Things. Thanks.

@ChetnaGupta

This comment has been minimized.

Copy link

commented Jun 10, 2019

Concise and helpful! Thanks

@droidada

This comment has been minimized.

Copy link

commented Jun 11, 2019

I'm going to have this framed on my office wall 😆 thanks 👍

@BenF-Lumedic

This comment has been minimized.

Copy link

commented Aug 1, 2019

If you're still maintaining this it would be useful to scope this to a specific version of enzyme or else update for latest version. I spent a little bit of time being confused about my test functionality before I realized that as of v3, shallow calls additional lifecycle methods.

@marin-k-marinov

This comment has been minimized.

Copy link

commented Aug 7, 2019

I have a question about testing a HOC component defined with withNavigation

class Device extends React.Component { ... }
export default withNavigation(Device)

When i try to shallow render it produces the following snapshot

<ContextConsumer>
  <Component />
</ContextConsumer>

I am not interested in testing the lifecycle of the component or behavior of componentDidMount, just want the snapshot to include the general structure and styling of the original <Device> component

@lukap2211

This comment has been minimized.

Copy link

commented Aug 22, 2019

@marin-k-marinov sounds like you just need render

@Dengyy

This comment has been minimized.

Copy link

commented Sep 29, 2019

Great,and hope the api docs can explain more

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.