Testing react-native-testing-library with react-navigation v5

2.1k views Asked by At

I'm looking to test react-navigation v5 with react-native-testing-library. The documentation says to do the following.

import React from 'react';
import { NavigationContainer } from '@react-navigation/native';
import { render, fireEvent } from '@testing-library/react-native';

describe('Testing react navigation', () => {
  test('page contains the header and 10 items', async () => {
    const component = (
      <NavigationContainer>
        <AppNavigator />
      </NavigationContainer>
    );

    const { findByText, findAllByText } = render(component);

    const header = await findByText('List of numbers from 1 to 20');
    const items = await findAllByText(/Item number/);

    expect(header).toBeTruthy();
    expect(items.length).toBe(10);
  });

 });

https://callstack.github.io/react-native-testing-library/docs/react-navigation

https://medium.com/@dariaruckaolszaska/testing-your-react-navigation-5-hooks-b8b8f745e5b6

This medium article suggests I create a MockedNavigator component. would this be a mockedNavigator component for all of my screens? Is this reusable?

import React from 'react';
import {NavigationContainer} from '@react-navigation/native';
import {createStackNavigator} from '@react-navigation/stack';

const Stack = createStackNavigator();
const MockedNavigator = ({component, params = {}}) => {
  return (
    <NavigationContainer>
      <Stack.Navigator>
        <Stack.Screen
          name="MockedScreen"
          component={component}
          initialParams={params}
        />
      </Stack.Navigator>
    </NavigationContainer>
  );
};

export default MockedNavigator;

The answer I'm looking for is. Am I to use the real AppNavigator component within all my unit tests or am I to use a MockedAppNavigator? Furthermore, how am I to pass props?

The documentation is unclear and I am looking for clarity. Many of the new components we are working with use hooks and the react-navigation-v5 is unable to access certain props.

1

There are 1 answers

0
Maciej Jastrzebski On

There are two recommended approaches for RNTL tests involving React Navigation.

  • Either you test the same navigators you use in your app. This does not have to be the whole AppNavigator if your tests contain nested navigators. It can be only the one you want to test.
  • Or you test single screen not connected to any navigator. This would probably require refactor of that screen into the React Navigation-aware XxxScreen that would not be tested and XxxScreenContent that would receive relevant props from XxxScreen but would be indenpendend of XxxScreen.

You can find more details in the official React Navigation example in RNTL repo.

The mocked navigator approach is possible but not really advised as it's mocking too much, as such tests frequently have to rely on implementation details not visible to the users like route names, navigator nesting, etc.