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

使用proxyquire搭配ES6 import时父上下文不可用的解决方法

问题:ES6模块环境下使用proxyquire mock依赖时报错TypeError: Cannot read properties of undefined (reading 'require')

待测试文件 migration_repository.js

import {getDatabaseName}  from "./maria_db_connector"

export default class MigrationRepository {
    getExistingVersions() {
        return getDatabaseName();
    }
}

被mock的模块 maria_db_connector.js

export function getDatabaseName() {
    return process.env.KOA_DATASOURCE_DATABASE;
}

当前测试代码

import MigrationRepository from './migration_repository.js'
import proxyquire from 'proxyquire';
const proxy = proxyquire.noCallThru(); 

describe('MigrationRepository', function () {

  beforeEach(function () {
    proxy.load('./migration_repository.js', {
      './maria_db_connector.js': {
        getDatabaseName: function () { return "test" },
      }
    })
  });
}

错误信息

运行命令 mocha *spec.js 时出现以下错误:

TypeError: Cannot read properties of undefined (reading 'require')

报错对应的代码行:

return this._withoutCache(this._parent, stubs, request, this._parent.require.bind(this._parent, request))

环境信息

devDependencies:

"devDependencies": {
    "mocha": "^10.2.0",
    "proxyquire": "^2.1.3",
    "sinon": "^15.0.2"
  }

Node.js版本:v18.15.0


解决方案

问题根源是proxyquire默认适配CommonJS模块,直接在ES6模块(使用import/export)环境下调用proxy.load会因缺少CommonJS的require上下文报错。针对ES6模块环境,需调整测试写法:

方案1:使用proxyquire适配ES模块的正确写法

不要提前用import导入待测试模块,完全通过proxyquire加载并mock依赖,同时声明ES模块标识:

import proxyquire from 'proxyquire';
const proxy = proxyquire.noCallThru(); 
import assert from 'assert';

describe('MigrationRepository', function () {
  let MigrationRepository;

  beforeEach(function () {
    // 通过proxyquire加载目标模块并mock依赖
    MigrationRepository = proxy('./migration_repository.js', {
      './maria_db_connector.js': {
        getDatabaseName: () => "test",
        esModule: true // 声明被mock的模块是ES模块
      }
    }).default; // ES模块默认导出需访问.default属性
  });

  it('should return test database name', function () {
    const repo = new MigrationRepository();
    const result = repo.getExistingVersions();
    assert.strictEqual(result, "test");
  });
});

方案2:确保Mocha支持ES模块(可选)

如果你的package.json中没有设置"type": "module",运行测试时需添加模块加载器参数:

mocha --loader esm *spec.js

Node.js 18+已原生支持ES模块,若package.json包含"type": "module",此步骤可省略。

关键注意事项

  • 禁止提前用import导入待测试模块,否则Node.js原生加载器会缓存模块,导致mock不生效。
  • 对ES模块进行mock时,必须在stub对象中添加esModule: true,否则proxyquire无法正确解析导出结构。
  • 通过proxyquire获取ES模块的默认导出时,必须访问.default属性,这是ES模块转CommonJS兼容层的规范要求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 07:25:14