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

Jest引用本地文件触发包链接错误问题求助

问题:React Native SDK单元测试中出现包未链接错误

项目结构

project  
│
└───src
│   └───__tests__
│   │   │   manager.test.txt
│   │
│   └───dictation
│        │   manager.ts
│        │   ...
│        └───src
│            └───exampleFileStream.ts               
│    
└───lib
│   │   ...
   
└───package.json
└───sdk.podspec
...

其中exampleFileStream.ts是依赖Native Modules的音频文件流类,被manager.ts引用。

package.json核心配置

{  
  "name": "sdk-test-project",
  "version": "0.1.3",
  "main": "src/index.tsx",
  "module": "lib/module/index",
  "types": "lib/typescript/index.d.ts",
  "react-native": "src/index",
  "source": "src/index",
  "devDependencies": {
    "@types/jest": "^28.1.2",
    "jest": "^28.1.1",
    "jest-websocket-mock": "^2.4.0",
    "react": "17.0.2",
    "react-native": "0.68.2",
    "react-native-builder-bob": "^0.18.3",
    "typescript": "^4.5.2"
  },
  "peerDependencies": {
    "react": "*",
    "react-native": "*"
  },
  "jest": {
    "preset": "react-native",
    "modulePathIgnorePatterns": [
      "<rootDir>/example/node_modules",
      "<rootDir>/lib/"
    ],
    "modulePaths": ["<rootDir>/app/"]
  },
  "react-native-builder-bob": {
    "source": "src",
    "output": "lib",
    "targets": [
      "commonjs",
      "module",
      [
        "typescript",
        {
          "project": "tsconfig.build.json"
        }
      ]
    ]
  }
}

测试代码

import WS from "jest-websocket-mock";
import { Manager } from '../../src/dictation/manager';


test('When onApiMessage enabled, only the callback is called', async () => {
    const server = new WS("ws://localhost:1234");
    const dm = Manager.method("");
    ...
});

运行Jest时的错误信息

The package 'sdk-test-project' doesn't seem to be linked. Make sure: 

    - You have run 'pod install'
    - You rebuilt the app after installing the package
    - You are not using Expo managed workflow

      15 |       {
      16 |         get() {
    > 17 |           throw new Error(LINKING_ERROR);
         |                 ^
      18 |         },
      19 |       }
      20 |     );

      at Object.get (src/dictation/core/exampleFileStream:17:17)
      at new addListener (node_modules/react-native/Libraries/EventEmitter/NativeEventEmitter.js:53:45)
      at new ExampleFileStream (src/dictation/core/exampleFileStream:37:26)
      at new Manager (src/dictation/manager.ts:116:32)
      at Function.fromCustomUrl (src/dictation/manager.ts:104:12)
      at fromCustomUrl (src/__tests__/manager.test.tsx:13:33)
      at tryCatch (node_modules/@babel/runtime/helpers/regeneratorRuntime.js:86:17)
      at Generator._invoke (node_modules/@babel/runtime/helpers/regeneratorRuntime.js:66:24)
      at Generator.next (node_modules/@babel/runtime/helpers/regeneratorRuntime.js:117:21)
      at tryCatch (node_modules/@babel/runtime/helpers/regeneratorRuntime.js:86:17)

用户疑问

为什么引用同项目本地文件会出现包未链接的问题?这是否和native modules有关?


原因分析

这个错误确实和Native Modules直接相关。你的exampleFileStream.ts里应该通过NativeModules或NativeEventEmitter引用了原生模块,而Jest运行在Node.js环境中,没有加载React Native的原生环境,当代码尝试访问未被模拟的原生模块时,就会触发React Native默认的“未链接”错误提示(这个提示原本是给原生模块未正确link的情况,但测试环境里根本不存在原生模块,所以同样会触发)。

解决方法

你需要在Jest测试中模拟这些依赖的Native Modules,以下是几种可行方案:

方案1:在测试文件中直接模拟Native Modules

在测试文件顶部添加模拟逻辑,覆盖React Native的原生模块:

jest.mock('react-native', () => {
  const originalRN = jest.requireActual('react-native');
  return {
    ...originalRN,
    NativeModules: {
      ...originalRN.NativeModules,
      // 替换成你实际依赖的原生模块名称和方法
      YourNativeAudioModule: {
        addListener: jest.fn(),
        removeListeners: jest.fn(),
        startStreaming: jest.fn(),
        // 其他需要的方法/属性
      },
    },
    NativeEventEmitter: jest.fn(() => ({
      addListener: jest.fn(),
      removeListener: jest.fn(),
    })),
  };
});

方案2:全局模拟原生模块

  1. 在项目根目录创建jest.setup.js文件,写入全局模拟逻辑:
jest.mock('react-native', () => {
  const originalRN = jest.requireActual('react-native');
  return {
    ...originalRN,
    NativeModules: {
      ...originalRN.NativeModules,
      YourNativeAudioModule: {
        addListener: jest.fn(),
        removeListeners: jest.fn(),
      },
    },
    NativeEventEmitter: jest.fn(() => ({
      addListener: jest.fn(),
    })),
  };
});
  1. 修改package.json中的Jest配置,引入这个全局 setup 文件:
"jest": {
  "preset": "react-native",
  "modulePathIgnorePatterns": [
    "<rootDir>/example/node_modules",
    "<rootDir>/lib/"
  ],
  "modulePaths": ["<rootDir>/app/"],
  "setupFilesAfterEnv": ["<rootDir>/jest.setup.js"]
}

方案3:直接模拟exampleFileStream.ts类

如果不想处理底层原生模块的模拟,可以直接模拟整个exampleFileStream.ts:

jest.mock('../../src/dictation/src/exampleFileStream.ts', () => {
  return {
    default: jest.fn(() => ({
      // 模拟你在测试中用到的类方法
      start: jest.fn(),
      on: jest.fn(),
      // 其他需要的方法
    })),
  };
});

总结

错误和本地文件引用无关,核心是Jest没有原生环境,任何依赖Native Modules的代码都必须被模拟才能正常运行。你看到的“未链接”提示是React Native在无法找到原生模块时的默认错误,本质是原生模块在测试环境中不存在。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 05:10:32