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

如何在Node.js的Jest测试中正确mock fs.readdir并解决ENOENT报错

问题修复方案

错误原因

你的写法不生效存在两个核心问题:

  1. 业务代码在模块初始化阶段就已经执行了const readdir = util.promisify(fs.readdir)赋值,测试用例中再监听util.promisify时,该赋值逻辑早已执行完成,监听逻辑无法拦截到已经生成的readdir方法。
  2. 直接对原始readdir变量调用mockReturnValueOnce无效,因为它本身不是Jest生成的Mock函数。

可行解决方案

方案一:直接Mock fs模块的readdir方法(最稳妥)

不管上层用什么工具包装回调方法,直接拦截底层fs.readdir即可:

const fs = require('fs');
// 替换为你的业务模块路径
const Files = require('./your-module-path');

// 全局mock整个fs模块
jest.mock('fs');

it('test read', async () => {
  // 模拟回调风格的readdir返回成功结果
  fs.readdir.mockImplementation((dirPath, callback) => {
    // 第一个参数为错误对象,传null表示调用成功,第二个参数为返回的文件列表
    callback(null, ['test1.js', 'test2.js']);
  });

  const result = await Files.test();
  expect(result).toEqual('success');
  // 可选:验证调用参数是否符合预期
  expect(fs.readdir).toHaveBeenCalledWith('directory path', expect.any(Function));
});

方案二:提前Mock util.promisify返回值

需要保证Mock逻辑执行在业务模块导入之前:

const util = require('util');

// 第一步:先监听util.promisify方法
const promisifySpy = jest.spyOn(util, 'promisify');
// 定义mock的readdir异步方法
const mockReaddir = jest.fn().mockResolvedValue(['test1.js', 'test2.js']);
// 让promisify调用后直接返回我们的mock方法
promisifySpy.mockReturnValue(mockReaddir);

// 第二步:再导入业务模块,此时业务模块中拿到的readdir就是我们的mock方法
const Files = require('./your-module-path');

it('test read', async () => {
  const result = await Files.test();
  expect(result).toEqual('success');
  expect(mockReaddir).toHaveBeenCalledWith('directory path');
});

你遇到的ENOENT报错本质是Mock逻辑未生效,代码依然调用了原生readdir读取不存在的路径,以上两种方案都可以规避对原生方法的调用,解决该报错。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 12:09:01