My ts-jest test of React Navigation fails with the error:
yarn run v1.22.10$ jestFAIL __tests__/App.spec.tsx● Test suite failed to run Jest encountered an unexpected token This usually means that you are trying to import a file which Jest cannot parse, e.g. it's not plain JavaScript. By default, if Jest sees a Babel config, it will use that to transform your files, ignoring "node_modules". Here's what you can do:• If you are trying to use ECMAScript Modules, see https://jestjs.io/docs/en/ecmascript-modules for how to enable it.• To have some of your "node_modules" files transformed, you can specify a custom "transformIgnorePatterns" in your config.• If you need a custom transformation specify a "transform" option in your config.• If you simply want to mock your non-JS modules (e.g. binary assets) you can stub them out with the "moduleNameMapper" config option. You'll find more details and examples of these config options in the docs: https://jestjs.io/docs/en/configuration.html Details: /home/rct/cod/rn-testing-issue-github-example/node_modules/react-native-iphone-x-helper/index.js:1 ({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,global,jest){import { Dimensions, Platform, StatusBar } from 'react-native'; ^^^^^^ SyntaxError: Cannot use import statement outside a module at Runtime.createScriptFromCode (node_modules/jest-runtime/build/index.js:1350:14) at Object.<anonymous> (node_modules/@react-navigation/bottom-tabs/lib/commonjs/views/SafeAreaProviderCompat.tsx:7:1)Test Suites: 1 failed, 1 totalTests: 0 totalSnapshots: 0 totalTime: 0.901 sRan all test suites.error Command failed with exit code 1.info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
The app works as expected in the emulator but I can't get tests running. Obviously, some sort of CommonJS/ESM configuration incompatibility above my pay grade, but I've been unable to resolve it after following half a dozen different tutorials :(
All ideas welcome!
Same issue posted in React Navigation issue tracker.
To reproduce:
git clone https://github.com/githorse/rn-testing-issue-example.gitcd rn-testing-issue-exampleyarn test
App.tsx(copied from React Navigation docs):
// App.tsximport * as React from 'react';import { Text, View } from 'react-native';import { NavigationContainer } from '@react-navigation/native';import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';function HomeScreen() { return (<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}><Text>Home!</Text></View> );}function SettingsScreen() { return (<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}><Text>Settings!</Text></View> );}const Tab = createBottomTabNavigator();export default function App() { return (<NavigationContainer><Tab.Navigator><Tab.Screen name="Home" component={HomeScreen} /><Tab.Screen name="Settings" component={SettingsScreen} /></Tab.Navigator></NavigationContainer> );}
App.spec.tsx:
// __tests__/App.spec.tsximport 'react-native';import React from 'react';import App from '../App';// Note: test renderer must be required after react-native.import renderer from 'react-test-renderer';jest.useFakeTimers();it('renders correctly', () => { renderer.create(<App />);});
babel.config.js from ts-jest React Native docs:
// babel.config.jsmodule.exports = { presets: ['module:metro-react-native-babel-preset'],}
jest.config.js from ts-jest React Native docs, adding the setupFiles
key referring to jest.setup.js
:
// jest.config.jsconst { defaults: tsjPreset } = require('ts-jest/presets')module.exports = { ...tsjPreset, preset: 'react-native', transform: { ...tsjPreset.transform,'\\.js$': '<rootDir>/node_modules/react-native/jest/preprocessor.js', }, globals: {'ts-jest': { babelConfig: true, }, }, // This is the only part which you can keep // from the above linked tutorial's config: cacheDirectory: '.jest/cache', setupFiles: ['<rootDir>/setup.jest.js' ]}
setup.jest.js from React Native Mocking Native Modules example, commenting out a line that produces another (presumably unrelated) error:
// setup.jest.jsimport 'react-native-gesture-handler/jestSetup';// import { cleanup } from '@testing-library/react-native';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 movedjest.mock('react-native/Libraries/Animated/NativeAnimatedHelper');