如何用Jest模拟process.cwd()函数?模拟失效问题排查
解决Jest中模拟process.cwd()在被测模块不生效的问题
嗨,这个问题我之前也碰到过!核心原因基本都是模块导入顺序搞的鬼~
如果你的被测模块是在你模拟process.cwd()之前就被导入了,那模块加载时已经把原始的process.cwd引用缓存下来了,后续你再修改process.cwd的模拟,根本影响不到模块里已经存好的那个引用,所以被测模块调用时还是返回原始值。
给你几个靠谱的解决方案:
方法一:调整顺序,先模拟再导入模块
把模拟process.cwd的代码放在导入被测模块的前面,这样模块加载时拿到的就是你模拟好的函数了:// 先搞定模拟 process.cwd = jest.fn(() => '/base/dir'); // 再导入被测模块 const myModule = require('./myModule'); test('验证cwd模拟生效', () => { expect(myModule.getCwd()).toBe('/base/dir'); });方法二:用resetModules+动态导入适配多测试用例
如果你的测试文件里有多个用例需要不同的cwd模拟值,可以在每个测试前重置模块缓存,再动态导入模块:beforeEach(() => { jest.resetModules(); // 清空模块缓存 process.cwd = jest.fn(() => '/base/dir'); }); test('测试基础目录场景', async () => { // 动态导入模块,确保每次都拿到最新的process引用 const myModule = await import('./myModule'); expect(myModule.getCwd()).toBe('/base/dir'); }); test('测试另一个目录场景', async () => { process.cwd = jest.fn(() => '/another/dir'); const myModule = await import('./myModule'); expect(myModule.getCwd()).toBe('/another/dir'); });方法三:用Jest的mockAPI更规范地模拟
你也可以直接用Jest的mock功能来覆盖process对象,这种方式更符合Jest的最佳实践:jest.mock('process', () => ({ ...jest.requireActual('process'), // 保留process的其他原始属性 cwd: jest.fn(() => '/base/dir') // 只替换cwd方法 })); const myModule = require('./myModule'); test('模拟cwd成功', () => { expect(myModule.getCwd()).toBe('/base/dir'); });
另外还要注意一个坑:如果你的被测模块里是把process.cwd()赋值给了一个变量,比如const currentDir = process.cwd(),然后后续用这个变量而不是直接调用process.cwd(),那即使你模拟了process.cwd,变量里存的还是原始值。这种情况要么调整模块代码,让它每次都直接调用process.cwd(),要么在模拟后手动修改那个变量(不过后者不太推荐,尽量让模块逻辑更利于测试)。
内容的提问来源于stack exchange,提问作者nidkil
相关产品推荐
相关产品推荐

