0

Trying to use Jest with ESM configuration to test React Native components and getting errors that Jest can't parse the imports from 'react-native'. The errors look like this: SyntaxError: The requested module 'react-native' does not provide an export named 'StyleSheet'. Any idea what I'm doing wrong?

RN version: 0.70.4

Example component:

import React, { ReactElement } from 'react';

import { StyleSheet, Text, View } from 'react-native';

const { container } = StyleSheet.create({
  container: {
    padding: 50,
  },
});

const ThisComponent = (): ReactElement => (
  <View style={container}>
    <Text>Hello World!</Text>
  </View>
);

export default ThisComponent;

Example test:

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

import ThisComponent from '../ThisComponent';

describe('<OTPInputs>', () => {
  test('Renders without exploding', async () => {
    const { getByText } = render(
      <ThisComponent />,
    );

    expect(getByText('Hello World!')).not.toBeDisabled();
  });
});

Jest config (in package.json):

 "jest": {
    "haste": {
      "defaultPlatform": "ios",
      "platforms": [
        "android",
        "ios",
        "native"
      ]
    },
    "resetMocks": true,
    "testEnvironment": "node",
    "testMatch": [
      "**/src/**/*.(spec|test).[tj]s?(x)"
    ],
    "preset": "ts-jest/presets/default-esm",
    "transform": {
      "^.+\\.js$": "babel-jest"
    },
    "transformIgnorePatterns": [
      "node_modules/(?!((jest-)?react-native|@react-native(-community)?)/)"
    ],
    "extensionsToTreatAsEsm": [
      ".ts",
      ".tsx"
    ],
    "globals": {
      "ts-jest": {
        "useESM": true
      }
    },
    "setupFiles": [
      "<rootDir>/node_modules/react-native/jest/setup.js"
    ],
    "setupFilesAfterEnv": [
      "@testing-library/jest-native/extend-expect"
    ],
    "moduleNameMapper": {
      "^~/(.*)$": "<rootDir>/src/$1",
      "^~components/(.*)$": "<rootDir>/src/components/$1",
      "^~util/(.*)$": "<rootDir>/src/util/$1",
      "^~types/(.*)$": "<rootDir>/src/types/$1"
    }
  }

EDIT: Looks like the main RN export is a cjs file with some weird syntax in it. Here is a mock that makes it work (with const ThisComponent = (await import('../ThisComponent').default):

jest.unstable_mockModule('react-native', () => ({
  __esModule: true,
  StyleSheet: jest.requireActual(
    'react-native/Libraries/StyleSheet/StyleSheet',
  ),
  Text: jest.requireActual('react-native/Libraries/Text/Text'),
  TextInput: jest.requireActual(
    'react-native/Libraries/Components/TextInput/TextInput',
  ),
  TouchableOpacity: jest.requireActual(
    'react-native/Libraries/Components/Touchable/TouchableOpacity',
  ),
  View: jest.requireActual('react-native/Libraries/Components/View/View'),
}));
nerdlinger
  • 1,610
  • 2
  • 17
  • 24

1 Answers1

0

Your Jest config looks quite complex and I suspect that it might be the reason. In general importing from react-native package should work out of the box in when using React Native Testing Library.

In case of config issue its always a good idea to start with a working step and then add additional config entries you need. In RNTL we have a basic example app that is useful for that purpose.

Maciej Jastrzebski
  • 3,674
  • 3
  • 22
  • 28