Testing React Native apps with Jest

Emily Xiong - May 6 '22 - - Dev Community

How to write unit and e2e tests for React Native apps using Jest in an Nx workspace

In my previous blog, I finally finished writing my awesome Nx React Native App. The app is running fine. Can I just commit my changes and call it a wrap?

No. As a disciplined developer, I know that finishing writing application code is only a job half done; the other half is writing tests.

This blog will go through:

  • How to write unit tests for React Native components
  • How to write e2e tests

Example Repo: https://github.com/xiongemi/studio-ghibli-search-engine


Unit Testing with Nx React Native

To run unit tests, simply run:

nx test <your app or lib>
Enter fullscreen mode Exit fullscreen mode

If you’re using Visual Studio Code, you can use Nx Console to run the test command:

Test command in Nx Console

You should see the unit test results in your terminal:

Test Suites: 10 failed, 1 passed, 11 total
Tests:       9 failed, 1 passed, 10 total
Snapshots:   0 total
Time:        9.84 s, estimated 21 s
Ran all test suites.
Enter fullscreen mode Exit fullscreen mode

This is what a starter unit test looks like:

Tech Stack

To write a unit test:

In your component, you can add testID:

<Headline testID='title'>{film.title}</Headline>
Enter fullscreen mode Exit fullscreen mode

Then in the test file, you can use function getByTestId to query testID:

const { getByTestId } = render(<your component>);
expect(getByTestId('title')).toHaveTextContent(...);
Enter fullscreen mode Exit fullscreen mode

You can view more queries here: https://callstack.github.io/react-native-testing-library/docs/api-queries.

The first time running the unit tests is unlikely to pass. There are usually a few errors I run into, I either have to fix the code and tests, or I need to mock some library.

Troubleshooting

Error: Jest failed to parse a file

If you are using libraries that contain native code, such as react-native-paper or @react-navigation/native, you are likely to run into the below error:

Jest encountered an unexpected token
Jest failed to parse a file. This happens e.g. when your code or its dependencies use non-standard JavaScript syntax, or when Jest is not configured to support such syntax.

To fix this, add that library name to transformIgnorePatterns in the jest.config.js.

For example:

transformIgnorePatterns: [
  'node_modules/(?!((jest-)?react-native|@react-native(-community)?)|expo(nent)?|@expo(nent)?/.*|@expo-google-fonts/.*|react-navigation|@react-navigation/.*|@unimodules/.*|unimodules|sentry-expo|native-base)',
],
Enter fullscreen mode Exit fullscreen mode

Error: Animated

If you use React Native’s Animated library or you use a material library like react-native-paper or react-native-elements, you are likely to get the below warning:

console.warn
Animated: useNativeDriver is not supported because the native animated module is missing. Falling back to JS-based animation. To resolve this, add RCTAnimation module to this app, or remove useNativeDriver. Make sure to run bundle exec pod install first. Read more about autolinking: https://github.com/react-native-community/cli/blob/master/docs/autolinking.md

In the test-setup file under your app or lib, add below mock:

jest.mock(
  '../../node_modules/react-native/Libraries/Animated/NativeAnimatedHelper'
);
Enter fullscreen mode Exit fullscreen mode

Error: Is your component inside a screen in a navigator?

If you use @react-navigation library for navigation, and inside your component, there are hooks from this library like useNavigation and useRoute, you are likely to get this error:

Couldn't find a route object. Is your component inside a screen in a navigator?

The easiest way to fix this is to mock the @react-navigation/native library like below in test-setup file under your app or lib:

Error: Could not find “store”

If your component is a smart component that uses Redux Store, you are going to get this error when testing that component:

Could not find "store" in the context of "Connect(Results)". Either wrap the root component in a , or pass a custom React context provider to and the corresponding React context consumer to Connect(Results) in connect options

To fix this, you need to wrap your component inside <Provider store={store}>.

First, you need to install redux-mock-store:

# npm
npm install redux-mock-store @types/redux-mock-store --save-dev

# yarn
yarn add redux-mock-store @types/redux-mock-store --dev
Enter fullscreen mode Exit fullscreen mode

The test would become:

Example unit test with different store states:

Here are how to write unit tests for React Native components and some common errors you are likely to run into.

Now with all the unit tests in place, you need to write e2e tests.


E2E Testing with Nx React Native

When generating an Nx React Native app, you should see a folder ends with e2e created.

To run the e2e tests against Debug build:

  • In one terminal, run nx start <your app>
  • In another terminal, run:
# iOS
nx test-ios <your app-e2e>

# Android
nx test-android <your app-e2e>
Enter fullscreen mode Exit fullscreen mode

If you want to run the e2e test against Release build, run:

# iOS
nx test-ios <your app-e2e> --prod

# Android
nx test-android <your app-e2e> --prod
Enter fullscreen mode Exit fullscreen mode

Tech Stack

Generally, the e2e tests should follow the below pattern:

For example, my app’s starter page looks like this:
Stater page

Here is my e2e test to check whether it displays the heading:

For my component, I added testID in order to be queried by e2e tests:

<SafeAreaView testID="search-page">
...
<Headline testID="heading">Studio Ghibli Search Engine</Headline>
Enter fullscreen mode Exit fullscreen mode

For example, my app has a flow that users can search text like totoro and go to the film details:
Search flow

The e2e test looks like this:

You can read more about matchers and actions in Detox here: https://wix.github.io/Detox/docs/api/matchers.


Conclusion

Here is how to test Nx React Native apps. With Nx, you do not need to explicitly install any testing library like Jest or Detox. So you can dive right in and focus on writing the tests rather than spending time on setup.

Check out my previous blog about Nx React Native:
https://dev.to/nx/share-code-between-react-web-react-native-mobile-with-nx-12eb

Where to go from here?

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .