1

I am testing the app navigation stack, and when rendering a very basic component it times out with the below error though there is no heavy loading in the component.

Error:

Ran all test suites.

error Command failed with exit code 1. info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command. nitinpiparava@Nitins-MacBook-Pro chronextapp % yarn run test yarn run v1.22.10 $ jest FAIL tests/AppStack-test.js (11.447 s) AppStack ✕ renders the correct screen (10007 ms)

● AppStack › renders the correct screen

thrown: "Exceeded timeout of 5000 ms for a test.
Use jest.setTimeout(newTimeout) to increase the timeout value, if this is a long-running test."

  21 |
  22 | describe('AppStack', () => {
> 23 |   it('renders the correct screen', async () => {
     |   ^
  24 |     const { getByText } = render(
  25 |       <NavigationContainer>
  26 |         <AppStack1 />

  at __tests__/AppStack-test.js:23:3
  at Object.<anonymous> (__tests__/AppStack-test.js:22:1)

Component

import React from 'react';
import { StyleSheet, Text, View, Button } from 'react-native';
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';

export const Screen1 = ({ navigation }) => (
  <View style={styles.container}>
    <Text>Screen 1</Text>
    <Button title='Go to Screen 2' onPress={() => navigation.push('Screen2')} />
  </View>
);

export const Screen2 = () => (
  <View style={styles.container}>
    <Text>Screen 2</Text>
  </View>
);

const Stack = createStackNavigator();
export const AppStack1 = () => (
  <Stack.Navigator>
    <Stack.Screen name='Screen1' component={Screen1} />
    <Stack.Screen name='Screen2' component={Screen2} />
  </Stack.Navigator>
);

const SignIn = () => (
  <View style={styles.container}>
    <Text>Sign In</Text>
  </View>
);

const AuthStack = () => (
  <Stack.Navigator>
    <Stack.Screen name='SignIn' component={SignIn} />
  </Stack.Navigator>
);

export default ({ isLoggedIn = true }) => (
  <NavigationContainer>
    {isLoggedIn ? <AppStack1 /> : <AuthStack />}
  </NavigationContainer>
);

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
});

Ject mock setup file

    import 'react-native-gesture-handler/jestSetup';

jest.mock('react-native-reanimated', () => {
  const Reanimated = require('react-native-reanimated/mock');

  // The mock for `call` immediately calls the callback which is incorrect
  // So we override it with a no-op
  Reanimated.default.call = () => {};

  return Reanimated;
});

//Silence the warning: Animated: `useNativeDriver` is not supported because the native animated module is missing
jest.mock('react-native/Libraries/Animated/NativeAnimatedHelper');

jest.mock('rn-fetch-blob', () => {
  return {
    __esModule: true,
    default: {
      fs: {
        unlink: jest.fn(),
      },
    },
  };
});

Jest Config

"jest": {
    "preset": "react-native",
    "moduleNameMapper": {
      ".+\\.(css|styl|less|sass|scss|png|jpg|ttf|woff|woff2)$": "identity-obj-proxy"
    },
    "setupFiles": [
      "./src/__mocks__/@react-native-async-storage/setup.js"
    ],
    "transform": {
      "^.+\\.jsx$": "babel-jest",
      "^.+\\.tsx$": "babel-jest"
    },
    "transformIgnorePatterns": [
      "node_modules/(?!@react-native|react-native)"
    ]
  },
  "resolutions": {
    "react-native/@jest/create-cache-key-function": "^27.0.2"
  }
Nitin
  • 7,455
  • 2
  • 32
  • 51
  • What version of react native and react navigation are you using? – Majed Badawi Sep 21 '21 at 08:49
  • @MajedBadawi "@react-navigation/bottom-tabs": "^5.11.11", "@react-navigation/native": "^5.9.4", "@react-navigation/stack": "^5.14.5", – Nitin Sep 21 '21 at 08:51
  • Did you setup the necessary mocks? – Majed Badawi Sep 21 '21 at 08:53
  • Yes I did In fact If I can also do snapshot testing through react-test-renderer but as soon as I use the render function from @testing-library/react-native i get this error, in my demo app it works fine – Nitin Sep 21 '21 at 08:57

1 Answers1

1

According to the documentation (5.x), you need to do the following in the jest setup file:

import 'react-native-gesture-handler/jestSetup';

jest.mock('react-native-reanimated', () => {
  const Reanimated = require('react-native-reanimated/mock');

  // The mock for `call` immediately calls the callback which is incorrect
  // So we override it with a no-op
  Reanimated.default.call = () => {};

  return Reanimated;
});

// Silence the warning: Animated: `useNativeDriver` is not supported because the native animated module is missing
jest.mock('react-native/Libraries/Animated/src/NativeAnimatedHelper');

// As of react-native@0.64.X file has moved
jest.mock('react-native/Libraries/Animated/NativeAnimatedHelper');

In the jest.config.js, try adding those to setupFiles where the first is the setup file you mentioned:

['./jestSetup.js', './node_modules/react-native-gesture-handler/jestSetup.js']

And set transformIgnorePatterns:

transformIgnorePatterns: [
  'node_modules/(?!(@react-native' +
    '|react-native' +
    '|react-navigation-tabs' +
    '|react-native-reanimated' +
    '|react-native-iphone-x-helper' +
    '|@react-navigation' +    
    '|@react-navigation/stack' +
  ')/)',
]
Majed Badawi
  • 27,616
  • 4
  • 25
  • 48