You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Native Jest测试报错:_reactNative.Linking.addEventListener不是函数

问题:React Native Jest测试报错:Linking相关异常

我在全新安装的React Native项目中运行默认Jest测试时遇到异常错误。

测试代码如下:

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 />);
});

我的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');

我的babel.config.js配置:

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

运行npm test(即jest命令)后,出现以下错误:

npm test

> optionscreener@0.0.1 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

我希望Jest和React Native能兼容运行,但目前未能实现,请问问题出在哪里?


解决方案

错误根源是React Navigation的useLinking钩子调用了Linking.addEventListener,但Jest默认的Linking mock没有提供该方法,同时测试中存在异步副作用未被正确处理,导致环境销毁后仍有代码执行。按以下步骤修复:

  1. 完善Linking模块的Mock
    在jest.setup.js中添加完整的Linking mock,覆盖所需方法:
jest.mock('react-native', () => {
  const originalModule = jest.requireActual('react-native');
  return {
    ...originalModule,
    Linking: {
      ...originalModule.Linking,
      addEventListener: jest.fn(),
      removeEventListener: jest.fn(),
      getInitialURL: jest.fn().mockResolvedValue(null),
    },
  };
});
  1. 异步处理测试中的副作用
    将测试改为异步函数,确保所有渲染相关的异步副作用完成后再结束测试:
it('renders correctly', async () => {
  await renderer.create(<App />);
});
  1. 确认Jest配置的测试环境
    在package.json或jest.config.js中检查测试环境设置,确保与React Native兼容:
// package.json中的jest配置示例
"jest": {
  "preset": "react-native",
  "setupFilesAfterEnv": ["./jest.setup.js"],
  "testEnvironment": "jsdom"
}
  1. 临时禁用Linking功能(可选)
    如果测试不需要路由跳转逻辑,可在测试时包裹App并禁用Linking:
import { NavigationContainer } from '@react-navigation/native';

it('renders correctly', () => {
  renderer.create(
    <NavigationContainer linking={{ enabled: false }}>
      <App />
    </NavigationContainer>
  );
});

内容的提问来源于stack exchange,提问作者fullStackChris

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 18:01:23