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

如何在Jest中Mock仅支持浏览器的@zip.js/zip.js库?

解决Jest中Mock仅支持浏览器的@zip.js/zip.js库问题

问题背景

项目引入的utils包依赖@zip.js/zip.js,但该库仅支持浏览器环境,无法在Node.js中运行。执行Jest测试时触发「Jest encountered an unexpected token」错误,提示import语句不能在模块外使用——这个错误信息存在误导性,实际核心问题是库不兼容Node.js环境,而非模块语法问题。

已尝试的无效方案:

  • 按Jest手动Mock文档创建__mocks__目录结构
  • 在测试文件首行添加jest.mock('@zip.js/zip.js')
  • 在package.json中设置"type": "module"及相关Issue解决方案

错误详情

FAIL  tests/index.test.ts
  ● Test suite failed to run

    Jest encountered an unexpected token

    This usually means that you are trying to import a file which Jest cannot parse, e.g. it's not plain JavaScript.

    By default, if Jest sees a Babel config, it will use that to transform your files, ignoring "node_modules".

    Here's what you can do:
     • If you are trying to use ECMAScript Modules, see https://jestjs.io/docs/en/ecmascript-modules for how to enable it.
     • To have some of your "node_modules" files transformed, you can specify a custom "transformIgnorePatterns" in your config.
     • If you need a custom transformation specify a "transform" option in your config.
     • If you simply want to mock your non-JS modules (e.g. binary assets) you can stub them out with the "moduleNameMapper" config option.

    You'll find more details and examples of these config options in the docs:
    https://jestjs.io/docs/en/configuration.html

    Details:

    ./node_modules/@zip.js/zip.js/index.js:29
    import Deflate from "./lib/core/codecs/deflate.js";
    ^^^^^^

    SyntaxError: Cannot use import statement outside a module

    > 1 | import {
        | ^
      2 |   Data64URIWriter,
      3 |   Entry,
      4 |   TextWriter,

      at Runtime.createScriptFromCode (../../node_modules/jest-cli/node_modules/jest-runtime/build/index.js:1350:14)
      at Object.<anonymous> (../utils/src/unzipFolder.ts:1:1)

Test Suites: 1 failed, 1 total
Tests:       0 total
Snapshots:   0 total
Time:        5.926 s

正确Mock方案

1. 配置Jest映射Mock文件

在Jest配置文件(jest.config.js/jest.config.ts)中添加moduleNameMapper,将@zip.js/zip.js直接映射到本地Mock文件,跳过对原库的解析:

module.exports = {
  // 保留原有配置
  moduleNameMapper: {
    '^@zip.js/zip.js$': '<rootDir>/__mocks__/zip.js'
  }
};

2. 创建Mock实现文件

在项目根目录新建__mocks__/zip.js,根据utils包中实际用到的导出内容,模拟对应的类和方法:

// 模拟你代码中用到的@zip.js/zip.js导出项
export class Data64URIWriter {
  write() {}
  close() { return Promise.resolve(); }
}

export class Entry {
  name = 'mock-entry';
  getData() {
    return Promise.resolve(new Blob(['mock-content']));
  }
}

export class TextWriter {
  content = '';
  write(chunk) { this.content += chunk; }
  close() { return Promise.resolve(this.content); }
}

// 若有其他用到的导出,按需添加模拟实现

3. 测试文件中自定义Mock行为(可选)

如果需要在特定测试中覆盖Mock逻辑,可在测试文件中重新Mock:

import { Data64URIWriter } from '@zip.js/zip.js';

jest.mock('@zip.js/zip.js', () => ({
  Data64URIWriter: jest.fn().mockImplementation(() => ({
    write: jest.fn(),
    close: jest.fn().mockResolvedValue('mock-base64')
  })),
  Entry: jest.fn().mockReturnValue({
    name: 'test-file.txt',
    getData: jest.fn().mockResolvedValue(new Blob(['test content']))
  })
}));

// 后续测试逻辑
test('unzipFolder works correctly', async () => {
  // ...测试代码
});

4. TypeScript类型兼容处理

如果是TypeScript项目,为避免类型报错,可在tsconfig.json中添加路径映射:

{
  "compilerOptions": {
    // 其他配置
    "paths": {
      "@zip.js/zip.js": ["__mocks__/zip.js"]
    }
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 16:45:44