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

React Native Jest测试中如何正确mock npm包方法

Jest 正确Mock React Native第三方npm包方法

核心错误原因

你之前的写法存在两个致命问题,导致mock不生效:

  • 两个功能包均为默认导出(export default),你之前的mock写的是命名导出结构,和包实际导出规则不匹配
  • 你将exitApp定义为返回jest.fn()的普通函数,exitApp本身不是mock函数,Jest无法追踪它的调用记录,断言自然无法通过

正确实现代码

1. 声明顶层Mock

在测试文件最顶部声明两个包的mock,严格匹配包的导出结构:

// Mock 应用退出包
jest.mock('react-native-exit-app', () => ({
  __esModule: true,
  default: {
    exitApp: jest.fn()
  }
}));

// Mock 应用重启包
jest.mock('react-native-restart', () => ({
  __esModule: true,
  default: {
    Restart: jest.fn()
  }
}));

2. 导入依赖并重置Mock状态

在mock声明之后导入依赖,每个用例执行前清空mock调用记录,避免用例间互相干扰:

import RNExitApp from 'react-native-exit-app';
import RNRestart from 'react-native-restart';
// 导入需要测试的业务模块/组件
import AppErrorBoundary from './your-business-file-path'; // 替换为实际业务文件路径

beforeEach(() => {
  jest.clearAllMocks();
});

3. 编写测试用例

针对不同场景编写断言,注意直接在导入的包实例上取方法做校验:

describe('应用配置校验逻辑', () => {
  test('配置缺失时触发应用退出', () => {
    // 模拟配置缺失的前置条件,比如mock配置模块返回configNotThere = true
    // 如果逻辑封装在组件中就渲染对应组件,封装在函数中就直接调用目标函数

    // 执行断言
    expect(RNExitApp.exitApp).toHaveBeenCalledTimes(1);
    expect(RNRestart.Restart).not.toHaveBeenCalled();
  });

  test('配置命中时触发应用重启', () => {
    // 模拟配置存在的前置条件,比如mock配置模块返回configFound = true
    // 执行业务逻辑

    // 执行断言
    expect(RNRestart.Restart).toHaveBeenCalledTimes(1);
    expect(RNExitApp.exitApp).not.toHaveBeenCalled();
  });
});

特殊场景处理

如果你的业务判断逻辑是写在模块顶层(即import模块时就会直接执行if判断,不是包裹在函数、组件生命周期内),需要用jest.isolateModules隔离模块加载时机,保证配置mock能在业务逻辑执行前生效:

test('顶层逻辑:配置缺失时退出应用', () => {
  jest.isolateModules(() => {
    // 先mock配置模块
    jest.mock('./app-config', () => ({
      configNotThere: true,
      configFound: false
    }));
    // 隔离上下文内加载业务模块,此时拿到的是mock后的配置
    require('./your-top-level-logic-file');
    // 断言
    expect(RNExitApp.exitApp).toHaveBeenCalledTimes(1);
  });
});

常见踩坑

  • 不要写exitApp: () => jest.fn():这种写法每次调用exitApp才会返回一个新的mock函数,exitApp本身没有被jest代理,无法统计调用次数
  • 不要断言未从mock模块导入的零散变量:必须通过导入的包默认实例访问对应方法做断言
  • 不要在mock声明前导入业务模块:Jest的mock提升仅对jest.mock生效,手动导入的业务模块如果在mock前加载,会拿到原始未mock的包,导致mock失效

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 19:24:22