使用Mocha和Proxyquire时出现TypeError: Cannot read 'require'错误,如何解决?
解决proxyquire报错TypeError: Cannot read properties of undefined (reading 'require')
问题原因
你用ES模块(import/export)编写测试,但原生proxyquire是为CommonJS模块设计的,ES模块环境中没有全局require对象,直接调用就会触发该错误。
解决方案
方案1:用proxyquire-esm适配ES模块
proxyquire-esm是专门针对ES模块场景的替代版本,操作步骤如下:
- 安装依赖
npm install proxyquire-esm --save-dev
- 修改测试代码
import { expect } from "chai"; import { mockReq, mockRes } from "sinon-express-mock"; import proxyquire from "proxyquire-esm"; import sinon from "sinon"; describe("Roles API", () => { afterEach(() => { sinon.restore(); }); it("should return roles on GET /roles", async () => { const req = mockReq(); const res = mockRes(); // 存根executeQuery方法 const executeQueryStub = sinon .stub() .resolves({ recordset: [{ id: 1, roleName: "Admin" }] }); // 使用proxyquire-esm替换目标模块的依赖 const rolesRouterWithStub = proxyquire("../src/Routes/Roles", { // 路径要和Roles模块中导入executeQuery的路径完全一致(包括扩展名,如.js) "../src/Utils/Db/index": { default: executeQueryStub } }); // 执行路由处理函数 await rolesRouterWithStub(req, res); // 断言验证 sinon.assert.calledOnce(executeQueryStub); sinon.assert.calledWithExactly(executeQueryStub, "SELECT * FROM Roles"); expect(res.send.calledOnceWithExactly([{ id: 1, roleName: 'Admin' }])).toBeTruthy(); }); });
方案2:确保路径匹配精准
如果你的目标模块(../src/Routes/Roles)中导入executeQuery时带了文件扩展名(比如../Utils/Db/index.js),那在proxyquire的替换配置里必须用完全一致的路径,否则替换失效,也可能间接引发错误。
方案3:通过Babel转译ES模块为CommonJS
如果坚持用原生proxyquire,可以配置Babel把测试代码和目标模块转译为CommonJS格式,确保测试环境中存在require对象。
内容的提问来源于stack exchange,提问作者Samuel Alli
相关产品推荐
相关产品推荐

