Home > Mobile >  React Native Jest Test TypeError: _reactNative.Linking.addEventListener is not a function
React Native Jest Test TypeError: _reactNative.Linking.addEventListener is not a function

Time:01-05

As the title states I'm getting a weird error with the default jest test that is included in a React Native fresh install. The actual test:

import 'react-native';
import React from 'react';
import App from '../src/App';

// Note: test renderer must be required after react-native.
import renderer from 'react-test-renderer';

it('renders correctly', () => {
  renderer.create(<App />);
});

My jest.setup.js:

// as supplied by the react navigation testing docs
import 'react-native-gesture-handler/jestSetup';

// Mock Ionicons pack
jest.mock('react-native-vector-icons/Ionicons', () => 'Icon');

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

My babel.config.js:

module.exports = {
  presets: ['module:metro-react-native-babel-preset'],
};

Then I just try to run npm test (i.e. jest), and I get the following errors:

npm test

> [email protected] test
> jest


ReferenceError: You are trying to `import` a file after the Jest environment has been torn down.

      at Object.prefixes [as Linking] (node_modules/react-native/index.js:320:12)
      at subscribe (node_modules/@react-navigation/native/src/useLinking.native.tsx:104:36)
      at node_modules/@react-navigation/native/lib/commonjs/useLinking.native.js:183:12
      at commitHookEffectListMount (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:12932:26)
      at commitPassiveMountOnFiber (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:14346:11)
      at commitPassiveMountEffects_complete (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:14306:9)
      at commitPassiveMountEffects_begin (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:14293:7)
      at commitPassiveMountEffects (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:14281:3)
      at flushPassiveEffectsImpl (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:16233:3)
      at flushPassiveEffects (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:16182:14)
      at node_modules/react-test-renderer/cjs/react-test-renderer.development.js:16002:9
      at workLoop (node_modules/scheduler/cjs/scheduler.development.js:266:34)
      at flushWork (node_modules/scheduler/cjs/scheduler.development.js:239:14)
      at Immediate.performWorkUntilDeadline [as _onImmediate] (node_modules/scheduler/cjs/scheduler.development.js:533:21)

 RUNS  __tests__/App-test.tsx
/Users/chris/enterprise/OptionScreener/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:2608
      throw error;
      ^

TypeError: _reactNative.Linking.addEventListener is not a function
    at subscribe (/Users/chris/enterprise/OptionScreener/node_modules/@react-navigation/native/src/useLinking.native.tsx:104:45)
    at /Users/chris/enterprise/OptionScreener/node_modules/@react-navigation/native/lib/commonjs/useLinking.native.js:183:12
    at commitHookEffectListMount (/Users/chris/enterprise/OptionScreener/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:12932:26)
    at commitPassiveMountOnFiber (/Users/chris/enterprise/OptionScreener/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:14346:11)
    at commitPassiveMountEffects_complete (/Users/chris/enterprise/OptionScreener/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:14306:9)
    at commitPassiveMountEffects_begin (/Users/chris/enterprise/OptionScreener/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:14293:7)
    at commitPassiveMountEffects (/Users/chris/enterprise/OptionScreener/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:14281:3)
    at flushPassiveEffectsImpl (/Users/chris/enterprise/OptionScreener/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:16233:3)
    at flushPassiveEffects (/Users/chris/enterprise/OptionScreener/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:16182:14)
    at /Users/chris/enterprise/OptionScreener/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:16002:9

Node.js v18.12.1

Just once I wish Jest and React Native would play nicely. But, once again, not today. Does anyone have any ideas as to what could be going wrong?

CodePudding user response:

Can you try using jest.useFakeTimers in your jest.setup.js

It’s just a guess but can you give it a try?

If this doesn‘t work can you change the implementation of AppState from:

  componentDidMount() {
    AppState.addEventListener(
      'change',
      this._handleAppStateChange
    );
  }

  componentWillUnmount() {
    AppState.removeEventListener(
      'change',
      this._handleAppStateChange
    );
  }

To the new version:

 useEffect(() => {
    const subscription = AppState.addEventListener("change", nextAppState => {});

    return () => {
      subscription.remove();
    };
  }, []);
  • Related