How to test React Native component with NavigationEvents in jest Code Answer

Hello Developer, Hope you guys are doing great. Today at Tutorial Guruji Official website, we are sharing the answer of How to test React Native component with NavigationEvents in jest without wasting too much if your time.

The question is published on by Tutorial Guruji team.

How can I write a jest unit test for a react native component which contains a NavigationEvents subcomponent.

I’ve tried the solutions offered in questions here and here without success.

The error I am getting is

    console.error node_modules/react-test-renderer/cjs/react-test-renderer.development.js:9215
      The above error occurred in the <Context.Consumer> component:
          in withNavigation(NavigationEvents) (created by MyComponent)
          in View (created by View)
          in View (created by MyComponent)
          in MyComponent

      Consider adding an error boundary to your tree to customize error handling behavior.

  ● MyComponent test › renders

    Invariant Violation: withNavigation can only be used on a view hierarchy of a navigator. The wrapped component is unable to get access to navigation from props or context.

Below is a minimal example that causes the error.

import 'react-native';
import { View } from 'react-native';
import { NavigationEvents } from 'react-navigation';
import React from 'react';
import renderer from 'react-test-renderer';

class MyComponent extends React.Component {

    constructor(props) {
      super(props);
    }

    render() {
        return (
          <View>
            <NavigationEvents/>
          </View>
        );}
  }

describe('MyComponent test', () => {
    it('renders', () => {

        jest.mock('react-navigation', () =>({
            NavigationEvents: 'mockNavigationEvents',
            withNavigation: component => component
          }));
        const navigation = { navigate: jest.fn() };

        renderer.create(<MyComponent navigation={navigation}/>);
    });
});

Edit

As requested in comments added package.json below:

{
  "main": "node_modules/expo/AppEntry.js",
  "scripts": {
    "start": "expo start",
    "android": "expo start --android",
    "ios": "expo start --ios",
    "eject": "expo eject",
    "test": "node ./node_modules/jest/bin/jest.js --watchAll"
  },
  "jest": {
    "preset": "jest-expo"
  },
  "dependencies": {
    "@expo/samples": "2.1.1",
    "@expo/vector-icons": "^10.0.0",
    "expo": "^35.0.0",
    "expo-camera": "~7.0.0",
    "expo-sqlite": "^7.0.0",
    "moment": "^2.24.0",
    "react": "16.8.3",
    "react-native": "https://github.com/expo/react-native/archive/sdk-35.0.0.tar.gz",
    "react-native-action-button": "^2.8.5",
    "react-native-calendar-picker": "^6.0.0",
    "react-native-dialog": "^5.6.0",
    "react-native-dotenv": "^0.2.0",
    "react-native-dynamic-search-bar": "^0.1.11",
    "react-native-elements": "^1.1.0",
    "react-native-gesture-handler": "~1.3.0",
    "react-native-keyboard-aware-scroll-view": "^0.9.1",
    "react-native-modal-datetime-picker": "^7.4.0",
    "react-native-paper": "^2.15.2",
    "react-native-progress-circle": "^2.1.0",
    "react-native-search-bar": "^3.4.2",
    "react-native-vector-icons": "^6.4.2",
    "react-navigation": "^3.0.9",
    "expo-constants": "~7.0.0",
    "expo-file-system": "~7.0.0"
  },
  "devDependencies": {
    "babel-preset-expo": "^7.0.0",
    "jest-expo": "^35.0.0"
  },
  "private": true
}

expo-cli version

$ expo-cli -V
3.13.1

Answer

The problem is that jest.mock has to be outside of describe and it functions. You don’t need to manually mock navigation object since you’re mocking the withNavigation HOC function:

// Setup mocks outside describe and it functions
jest.mock('react-navigation', () =>({
  NavigationEvents: 'mockNavigationEvents',
  withNavigation: component => component
}));

class MyComponent extends React.Component {
  constructor(props) {
    super(props);
  }

  render() {
    return (
      <View>
        <NavigationEvents/>
      </View>
    );
  }
}

describe('MyComponent test', () => {
  it('renders', () => {
    renderer.create(<MyComponent/>);
  });
});

And the renders test passes:

Jest test renders

I suggest you have all those mocks inside a file and set setupFilesAfterEnv in package.json:

package.json > jest:

"jest": {
  "preset": "jest-expo"
  "setupFilesAfterEnv": ["./path/to/jestInit.js"]
},

jestInit.js:

jest.mock('react-navigation', () =>({
  NavigationEvents: 'mockNavigationEvents',
  withNavigation: component => component
}));

This way, you’ll have those mocks for every Jest test file without having to include the mocks inside each test file.

We are here to answer your question about How to test React Native component with NavigationEvents in jest - If you find the proper solution, please don't forgot to share this with your team members.

Related Posts

Tutorial Guruji