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

Jest测试时TurboModuleRegistry.getEnforcing找不到NativeAppInfo模块的报错求助

Jest测试时TurboModuleRegistry.getEnforcing找不到NativeAppInfo模块的报错求助

问题描述

我的React Native项目在Android真机和模拟器上运行完全正常,页面中调用NativeAppInfo这个TurboModule也没有问题,但Jest测试一直失败。

我的NativeAppInfo模块代码

import type { TurboModule } from "react-native";
import { TurboModuleRegistry } from "react-native";

export interface Spec extends TurboModule {
  getAppVersion(): string;
}

export default TurboModuleRegistry.getEnforcing<Spec>("NativeAppInfo");

Jest报错信息

FAIL __tests__/App.test.tsx
● Test suite failed to run

Invariant Violation: TurboModuleRegistry.getEnforcing(...): 'NativeAppInfo' could not be found. Verify that a module by this name is registered in the native binary.

  6 | }
  7 | > 8 | export default TurboModuleRegistry.getEnforcing<Spec>("NativeAppInfo");
     | ^
  9 | at invariant (node_modules/invariant/invariant.js:40:15)
    at Object.getEnforcing (node_modules/react-native/Libraries/TurboModule/TurboModuleRegistry.js:47:12)
    at Object.getEnforcing (specs/NativeAppInfo.ts:8:36)
    at Object.require (src/pages/settings/index.tsx:11:1)
    at Object.require (src/router/StackProfileNavigator.tsx:9:1)
    at Object.require (src/router/BottomTabMenuNavigator.tsx:14:1)
    at Object.require (src/router/StackRootNavigator.tsx:8:1)
    at Object.require (src/router/index.tsx:1:1)
    at Object.require (App.tsx:6:1)
    at Object.require (__tests__/App.test.tsx:5:1)

Test Suites: 1 failed, 3 passed, 4 total
Tests: 4 passed, 4 total
Snapshots: 2 passed, 2 total
Time: 2.057 s, estimated 8 s
Ran all test suites.

我的Jest配置

/**
 * @type {import("jest").Config}
 */
module.exports = {
  preset: "react-native",
  transformIgnorePatterns: [
    "node_modules/(?!(@react-native|react-native|@react-navigation)/)",
  ],
  moduleNameMapper: {
    "\\.(ttf)$": "<rootDir>/__mocks__/file-mock.js",
  },
  setupFiles: ["<rootDir>/__mocks__/jestSetupFiles/setup.js"],
};

我试过很多方法都没解决,有没有大佬能救救我?


解决方案

别慌,这个问题我之前也碰到过!你的项目在Android上能正常运行,是因为原生端已经注册了NativeAppInfo这个TurboModule,但Jest是纯JavaScript的测试环境,根本没法加载原生代码,所以才会抛出这个找不到模块的错误。咱们只需要给这个TurboModule写个Mock就能解决,下面给你几个实用的方案:

方案一:全局Mock(推荐,一次配置所有测试生效)

你已经在jest.config里配置了setupFiles指向__mocks__/jestSetupFiles/setup.js,直接在这个setup文件里添加Mock代码就行:

import { TurboModuleRegistry } from 'react-native';

// Mock TurboModuleRegistry,针对NativeAppInfo返回模拟实现
jest.mock('react-native/Libraries/TurboModule/TurboModuleRegistry', () => {
  const originalModule = jest.requireActual('react-native/Libraries/TurboModule/TurboModuleRegistry');
  
  return {
    ...originalModule,
    getEnforcing: jest.fn((moduleName) => {
      // 只针对我们的NativeAppInfo做Mock,其他模块保持原逻辑
      if (moduleName === 'NativeAppInfo') {
        return {
          getAppVersion: jest.fn(() => '1.0.0'), // 这里可以自定义模拟返回的版本号
        };
      }
      return originalModule.getEnforcing(moduleName);
    }),
  };
});

保存后重新跑测试,应该就能绕过这个错误了。

方案二:在模块文件里做环境判断导出

如果你不想全局Mock,也可以直接在NativeAppInfo.ts里根据环境做条件导出:

import type { TurboModule } from "react-native";
import { TurboModuleRegistry } from "react-native";

export interface Spec extends TurboModule {
  getAppVersion(): string;
}

let NativeAppInfo: Spec;

// 测试环境下用模拟实现,生产/开发环境用真实的TurboModule
if (process.env.NODE_ENV === 'test') {
  NativeAppInfo = {
    getAppVersion: () => '1.0.0',
  } as Spec;
} else {
  NativeAppInfo = TurboModuleRegistry.getEnforcing<Spec>("NativeAppInfo");
}

export default NativeAppInfo;

这种方式更贴近模块本身的逻辑,也不用改动Jest的全局配置。

方案三:在单个测试文件里局部Mock

如果只是某个测试文件需要用到这个模块,也可以在测试文件顶部直接Mock:

// 在__tests__/App.test.tsx顶部添加
jest.mock('../specs/NativeAppInfo', () => ({
  default: {
    getAppVersion: jest.fn(() => '1.0.0'),
  },
}));

这种方式适合只需要在特定测试中覆盖的场景。

补充说明

你可以根据自己的测试需求调整Mock函数的返回值,比如getAppVersion可以返回不同的版本号,用来测试不同的业务逻辑。

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.08 10:58:08