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

使用Jest部分Mock AdmZip时getEntries()原方法报错如何解决

Jest Mock adm-zip 保留原生实例方法问题

问题背景

尝试了所有公开的相关示例写法均无法正常运行,其中最接近预期思路的写法实际执行依旧存在问题。

实现目标

保留AdmZip所有原生方法的原有逻辑,仅对writeZip和updateFile两个方法进行Mock,后续可通过Spy对这两个方法的调用情况做断言校验。

现存报错

运行代码时抛出admZip.getEntries() is not a function错误,初步判断是Mock逻辑中引入实际模块的写法有误,需要找到正确的Mock写法,保留getEntries等所有AdmZip原生实例方法。

已尝试的失败写法

  • 第一种写法:
jest.mock('adm-zip', () => {
  const actual = jest.requireActual('adm-zip');
  return function(): AdmZip {
      return {
        ...actual, // 原本期望通过展开操作符引入getEntries()等原生方法
        writeZip: jest.fn(),
        updateFile: jest.fn()
      }
  }
});
  • 第二种写法:
jest.mock('adm-zip', () => {
  const actual = jest.requireActual('adm-zip');
  return jest.fn().mockImplementation(() => ({
    ...actual,
    writeZip: jest.fn(),
    updateFile: jest.fn()
  }))
});
  • 第三种写法:
jest.mock('adm-zip', () => {
  const actual = jest.requireActual('adm-zip');
  return {
    __esModule: true,
    ...actual,
    AdmZip: jest.fn().mockImplementation(() => {
      return {
        ...jest.requireActual('adm-zip'),
        writeZip: jest.fn(),
        updateFile: jest.fn()
      }
    })
  }
});

错误原因

三种写法的核心问题:jest.requireActual('adm-zip')获取到的是模块导出的AdmZip构造函数,而非构造函数的原型对象。getEntries等实例方法都挂载在构造函数的prototype上,直接展开构造函数本身根本拿不到这些实例方法,最终生成的Mock对象自然缺少对应方法,调用时就会抛出is not a function的错误。

正确实现方案

核心思路是先创建真实的AdmZip实例(自带所有原生原型方法),再在这个真实实例上覆盖需要Mock的两个方法即可,不需要手动搬运原型方法。

CommonJS 导入场景(const AdmZip = require('adm-zip'))

jest.mock('adm-zip', () => {
  const actualAdmZip = jest.requireActual('adm-zip');
  // 兼容不同版本的导出差异
  const AdmZipConstructor = actualAdmZip.default || actualAdmZip;
  return jest.fn().mockImplementation((...constructorArgs) => {
    // 生成真实实例,自带所有原生方法
    const realInstance = new AdmZipConstructor(...constructorArgs);
    // 仅覆盖需要Mock的两个方法
    realInstance.writeZip = jest.fn();
    realInstance.updateFile = jest.fn();
    return realInstance;
  })
});

ES Module 导入场景(import AdmZip from 'adm-zip' / import { AdmZip } from 'adm-zip')

jest.mock('adm-zip', () => {
  const actualAdmZip = jest.requireActual('adm-zip');
  const AdmZipConstructor = actualAdmZip.default || actualAdmZip;
  const mockFactory = jest.fn().mockImplementation((...constructorArgs) => {
    const realInstance = new AdmZipConstructor(...constructorArgs);
    realInstance.writeZip = jest.fn();
    realInstance.updateFile = jest.fn();
    return realInstance;
  });
  return {
    __esModule: true,
    ...actualAdmZip,
    default: mockFactory,
    AdmZip: mockFactory
  }
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 01:51:21