---
title: "Testing React Native With the New Jest - Part I"
description: "A step by step guide to testing React Native with the Jest. Part One - Snapshots come into play."
url: https://www.callstack.com/blog/testing-react-native-with-the-new-jest-part-1-snapshots-come-into-play
updated: 2026-10-24T08:39:38.064Z
---

# Testing React Native With the New Jest - Part I

A step by step guide to testing React Native with the Jest. Part One - Snapshots come into play.

_By Ferran Negre, Software Engineer @ Callstack · Published 2016-09-09 · Category: Testing_

In my journey with [React](https://facebook.github.io/react/), I have been always testing and encouraging people who surround me to test their apps. I have always used [Jest](https://facebook.github.io/jest/) for it. But let’s not talk about it again and let’s focus on [React Native](https://facebook.github.io/react-native/). Wouldn’t it be nice to use the same framework to test our amazing mobile apps? Furthermore… Wouldn’t it be nice to reuse some tests if we are reusing logic between our web app and our mobile app?

I will try to answer those questions in the following series. In this first article, I will focus on testing React Native components and the pros and cons of using the new Snapshot system provided by Jest vs. shallow rendering comparison (test utils and Enzyme).

### Why the new Jest?

Before you ask me why I am calling it the _new_ Jest, please check out the updates notes from [Jest 14](https://facebook.github.io/jest/blog/2016/07/27/jest-14.html) and [Jest 15](https://facebook.github.io/jest/blog/2016/09/01/jest-15.html). It is not only me who says that Jest has a total new face compared to 1 year ago… It is also his number one core contributor:

> > yeah, it has nothing to do with what Jest was then. Just the same name and logo.
> > 
> > — Christoph Nakazawa (@cpojer) [September 2, 2016](https://twitter.com/cpojer/status/771743764310323201?ref%5Fsrc=twsrc%5Etfw)

[Post on X](https://twitter.com/cpojer/status/771743764310323201)

In this series we will focus on one of the new Jest features: Snapshot testing.

Jest can [capture snapshots](https://facebook.github.io/jest/docs/tutorial-react.html#snapshot-testing) of React trees or other serializable values to write tests quickly and it provides a seamless update experience.

Let’s begin to prove the above quote!

### Set up Jest in a React Native project

Trivial, seriously. Just follow the [docs](https://facebook.github.io/jest/docs/tutorial-react-native.html#setup):

[GitHub Gist](https://gist.github.com/callstack-bot/8f516e8d5959a96ca4689179b347d727)

DONE. Try it out with:

[GitHub Gist](https://gist.github.com/callstack-bot/c7163cce745c5cc00ddf6ca33c74bcb5)

## Time to test components

The [example repo](https://github.com/ferrannp/react-native-testing-example) for this article renders a list of Github repositories. You can read several test examples in there but for the purpose this article, let’s focus on testing a simple component called RepoItem:

[GitHub Gist](https://gist.github.com/ferrannp/cb9cfa3927052259c469c4e30576d202)

A [full file](https://github.com/ferrannp/react-native-testing-example/blob/master/app/components/RepoItem.js) includes the props definition and styles.

This component has an interesting prop called _isSelected._ When isSelected = true, then the item renders with a green background.

## The problems of Shallow Rendering comparison

Have you ever used [Shallow rendering](https://facebook.github.io/react/docs/test-utils.html#shallow-rendering) from [react-addons-test-utils ](https://facebook.github.io/react/docs/test-utils.html#shallow-rendering)or [Enzyme](https://github.com/airbnb/enzyme)? They are pretty similar, Enzyme got popular cause it has a nicer API which also allows you to find elements in your React trees. Let’s choose this one and try to test a React Native component using it.

### **Enzyme**

First problems when trying to use the [shallow](https://github.com/airbnb/enzyme/blob/master/docs/api/shallow.md) function from Enzyme (forget about [mount](https://enzymejs.github.io/enzyme/docs/guides/jsdom.html#using-enzyme-with-jsdom) in react-native):

react-addons-test-utils is an implicit dependency in order to support react@0.13–14. Please add the appropriate version to your devDependencies. See https://github.com/airbnb/enzyme#installation

react-dom is an implicit dependency in order to support react@0.13–14. Please add the appropriate version to your devDependencies. See https://github.com/airbnb/enzyme#installation

npm install react-dom react-addons-test-util --save-dev

So we actually need to install _react-dom_ and _react-addons-test-util_ to our _devDependencies_ for Enzyme to work… Ouch!:

Ok, let’s go and try to do the first full shallow comparison:

[GitHub Gist](https://gist.github.com/ferrannp/36537334d5b7bb9c1b4ec7def3893b09)

The onPress function will make this test to fail.

Ok, actually, this first example won’t work. See the _onPress_ property? The first problem that we have here is the way it’s defined in the component:

[GitHub Gist](https://gist.github.com/callstack-bot/a0924ce4e53174b414555961baf6c33a)

Both functions won’t be the same (we are creating a new function instance) thus the comparison will fail. We could make some workarounds here but… Let’s be lazy and skip the _TouchableHighlight_part and assume that nobody will break it:

[GitHub Gist](https://gist.github.com/ferrannp/7ff7487086610ea324b68db7cd06f1af)

This will work but…

Don’t you feel we are reimplementing the _render()_ again? Any prop you add/remove or any change you make… You need to come back here and do the same.

All right, now we want to test the component when the prop _isSelected_ is set to true:

[GitHub Gist](https://gist.github.com/ferrannp/467ddaa7ab793fb32db006948ce3c22e)

Copy-paste-copy-paste…

Since recreating the bigger picture gets so repetitive, developers tend to test only the _dynamic parts_, see:

[GitHub Gist](https://gist.github.com/ferrannp/d4ccebc0a829a7fa8975be4c8897fbff)

Yes, you can create a function that gives you the shallow component and accepts the _isSelected_ prop

This seems better, right? Let’s continue…

Assume that at some point on this project, our client decides that when you click a list item, a part from the selected background color, we also want to show more information, specifically, the repo description. When isSelected = true, the item renders with a green background and shows the repo description

With this change, two things will happen:

1. The test that checks all the render output will fail: We will need to go back and reimplement it
2. The test that checks only the dynamic part will pass anyway (Oops! is that good?)

In the first case, we need to go back and copy-paste this line into it’s corresponded place:

[GitHub Gist](https://gist.github.com/ferrannp/abb638430fa11e0476bf475f667b0820)

When isSelected prop is true

In the second case, we need to remember to go back to the test and add the new cases:

[GitHub Gist](https://gist.github.com/ferrannp/20cd7892f3c31cf74f83f2b9a238f03d)

New cases

Do you see the problems? The way I see it… The bigger picture (full render) is complicated to create, tedious to maintain and very repetitive (copy-paste). The second approach (using find, contains…) is unstable: We need to remember to implement all the cases since the new ones won’t break those tests.

Check the full [RepoItem-Shallow-test.js](https://github.com/ferrannp/react-native-testing-example/blob/master/app/components/__tests__/RepoItem-Shallow-test.js) file for a bigger picture.

### Shallow rendering summary

#### **Pros**

- Powerful selector api (find, contains, etc)
- It is actually working in React Native (shallow part)

#### **Cons**

- It feels you are repeating yourself all the time, thus, people will usually tend to test only specific parts of the output (render) instead of the big picture
- Copy-paste from the component to the test
- Difficult to maintain
- Go try convincing people to write them

### Snapshots to the rescue

Jest 14 introduced Snapshots testing: Check out [why they are so great](https://facebook.github.io/jest/blog/2016/07/27/jest-14.html#why-snapshot-testing):

No flakiness: Because tests are run in a command line runner instead of a real browser or on a real phone, the test runner doesn’t have to wait for builds, spawn browsers, load a page and drive the UI to get a component into the expected state which tends to be flaky and the test results become noisy.

Fast iteration speed: Engineers want to get results in less than a second rather than waiting for minutes or even hours. If tests don’t run quickly like in most end-to-end frameworks, engineers don’t run them at all or don’t bother writing them in the first place.

Debugging: It’s easy to step into the code of an integration test in JS instead of trying to recreate the screenshot test scenario and debugging what happened in the visual diff.

After the read, let’s try it out and convince ourselves.

We can write a Snapshot test for our first RepoItem (when isSelected is set to false):

[GitHub Gist](https://gist.github.com/ferrannp/7035f37e760390d5017ec8f9be5f7d9f)

Check the result at: [RepoItem-Snapshot-test.snap](https://github.com/ferrannp/react-native-testing-example/blob/master/app/components/__tests__/__snapshots__/RepoItem-Snapshot-test.js.snap). You will find that it does not use the background color property (as expected) because isSelected is false:

[GitHub Gist](https://gist.github.com/callstack-bot/188eadff4f0bd98db8e1ee108f8a62ed)

Now, let’s test the output when isSelected is set to true (it needs to render a green background). Since our component is actually a pure function, this becomes trivial:

[GitHub Gist](https://gist.github.com/ferrannp/71f556f1bdcd7dbba447adf25d160fe2)

And we can find the expected part inside the resulted snapshot [RepoItem-Snapshot-test.snap](https://github.com/ferrannp/react-native-testing-example/blob/master/app/components/__tests__/__snapshots__/RepoItem-Snapshot-test.js.snap):

[GitHub Gist](https://gist.github.com/callstack-bot/c008d4619ce5ae5e7fb62a1b02c003c3)

Great! Now, remember that our client came and asked us to implement the expanded part to show the repo description (a part from the background color). Let’s run the tests.

Oops! A test has failed.

Let’s check why. At developing time, Jest will show us very useful error outputs (you can use the [watch](https://facebook.github.io/jest/#use-the-interactive-mode-mode-to-automatically-re-run-tests) argument to see them live). Since this change is expected, we can run:

[GitHub Gist](https://gist.github.com/callstack-bot/1ace3da74bd349d19c39296ca09222f5)

And that will update our snapshot for free. Check it out:

[GitHub Gist](https://gist.github.com/callstack-bot/1cdabded81e67691ed9b69a1255080d4)

Boom! Our test failed, we inspected it, the failure was expected and we re-generated the snapshot. We did not have to modify our test. Moreover, this snapshot difference will be shown in our next Pull Request.

And that is all, seriously. Our render output is fully tested for both cases and it is capable to _react_ to changes giving us nice error outputs and an easy way to fix them. Quiet neat, right?

#### **Can I test components with internal state?**

Before you ask, yes, you can. Check this example in the Jest repo: [Link.react-test.js](https://github.com/facebook/jest/blob/master/examples/snapshot/__tests__/Link.react-test.js). Of course, if your component has internal state (side effects), it will get much more complicated to test. See:

I am missing a selector api like Enzyme

Especially if your component has state and you need to trigger some event, it can be very tedious to find the node inside the tree. However, this question has been already asked at [Jest issues](https://github.com/facebook/jest/issues/1411) and it has an official answer:

> We are working on a selector API for the test renderer which will make this possible through an official API — [Christoph Pojer](https://medium.com/u/9ea60eb6fc7c)

#### Snapshots summary

Pros

- Easy to write
- Don’t repeat yourself ([DRY](https://en.wikipedia.org/wiki/Don%27t_repeat_yourself))
- Compatible with React Native: Check [RepoList-Snapshot-test.js](https://github.com/ferrannp/react-native-testing-example/blob/master/app/components/__tests__/RepoList-Snapshot-test.js) and its [snapshot ](https://github.com/ferrannp/react-native-testing-example/blob/master/app/components/__tests__/__snapshots__/RepoList-Snapshot-test.js.snap)which renders a ListView with its items (try to do that without snapshots if you can)
- Error messages on develop time (you can use —watch t00)
- More goodies to come!

Cons

- Missing a selector API like Enzyme (but you read above that Jest community is working on it)
- Snapshots can be huge and sometimes it might be tedious to find the part you are looking for (lot of noise). In contrast, pull requests will highlight any changes for you. Update 27 Jul 2017: We created [snapshot-diff](https://github.com/jest-community/snapshot-diff) to overcome this issue. Third part of this article is coming soon.
- I am missing a comparison-tool-like between Snapshots. In my example, I manually need to look the differences between the Snapshot with _isSelected_ set to false vs. _isSelected_ set to true

### What is the true value of Snapshots?

I want to wrap up stressing the pull request part again. From [Kent C. Dodds](https://medium.com/u/db72389e89d8):

> > .@spencercarnage that's not where the value is... The value is in this \[1\] at develop time and this \[2\] at PR time [pic.twitter.com/ULlRaD4EIZ](https://t.co/ULlRaD4EIZ)
> > 
> > — Kent C. Dodds 💿🔴 (@kentcdodds) [September 4, 2016](https://twitter.com/kentcdodds/status/772289036278870016?ref%5Fsrc=twsrc%5Etfw)

[Post on X](https://twitter.com/kentcdodds/status/772289036278870016)

I could not agree more: Code reviews shine using snapshots. But, be aware then that for the Snapshot concept to work you need to:

> > but I need to stress that when using snapshots it's integral that the resulting file is being reviewed properly.
> > 
> > — Christoph Nakazawa (@cpojer) [September 5, 2016](https://twitter.com/cpojer/status/772815232372572160?ref%5Fsrc=twsrc%5Etfw)

[Post on X](https://twitter.com/cpojer/status/772815232372572160)

Which means:

You need to make sure that the \_\_snapshots\_\_ folders are reviewed in your PRs

Let me add yet another value: Don’t repeat yourself. This has been demonstrated (I hope!) here when we do not have to re-rewrite our component output. But if you want to go further on that, check out the next article of this series.

And if your team could use help from senior developers, check out our [React Native development services](https://www.callstack.com/react-native-development-company). We’d love to talk and find out how we can take your React Native project to the next level together.
