Vitest中使用memfs模拟fs模块报readdirSync非函数的导出问题
问题原因
导出结构和原生fs模块不匹配。
你用import * as fs from "fs"导入时,拿到的是模块的所有顶级导出集合;但当前模拟文件只导出了一个叫fs的命名属性,readdirSync等方法都挂在这个属性指向的memfs实例上,没有直接暴露到模块顶级,调用自然会报错。
正确写法
修改./__mocks__/fs.ts的导出逻辑,将memfs生成的模拟fs实例的所有方法直接作为模块顶级导出,同时兼容CJS/ESM两种导入规范即可:
// __mocks__/fs.ts import { createFsFromVolume, Volume } from "memfs" const musicFolder = "./musicFolder" const files = { "./1.mp3": "1", "./2.mp3": "2", } const volume = Volume.fromJSON(files, musicFolder) const mockFs = createFsFromVolume(volume) // 导出结构和原生fs完全一致 Object.assign(exports, mockFs) export default mockFs
测试文件不需要额外修改,保持原有写法即可正常运行:
// test.spec.ts import { describe, expect, it, vi } from "vitest" import * as fs from "fs" vi.mock("fs") it("testing fs", async () => { const files = fs.readdirSync("./musicFolder") expect(files).toBeTruthy() })
注意事项
- 确保
__mocks__文件夹放在Vitest配置的项目根目录下,或者和测试文件同级,否则Vitest无法自动加载手动模拟文件 createFsFromVolume返回的实例已经包含所有原生fs的同步、异步、promise风格API,不需要额外手动补全- 如果需要在单个测试中修改文件系统内容,可以在模拟文件中额外导出
volume实例,测试时直接操作volume即可更新mock文件结构
内容的提问来源于stack exchange,提问作者Woww
相关产品推荐
相关产品推荐

