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

使用Jest模拟Node.js的fs模块失效,求正确模拟方法

问题:Jest模拟fs模块失效,触发真实文件读取错误

我正在使用TypeScript、Jest、ts-node,尝试模拟fs模块的部分函数来测试自定义模块。

tsconfig.json核心配置如下:

...
 "target": "ESNext",
 "module": "NodeNext",
 "moduleResolution": "nodenext",  
...

测试文件mocking.test.ts代码如下:

import * as fs from 'fs';
import { jest } from '@jest/globals'

jest.mock("fs", () => ({
    readFileSync: jest.fn().mockReturnValue("test"),
}));

describe('mock test', () => {
    it('should read file content', () => {
        expect(fs.readFileSync("abcd.test", "utf8")).toBe("test"); // 运行时触发错误:ENOENT: no such file or directory, open 'abcd.test' 
    });
});

运行测试时触发了真实fs模块的文件不存在错误,模拟未生效,请问原因是什么?该如何正确模拟?


原因分析

你的tsconfig配置了module: NodeNext和moduleResolution: nodenext,这会让项目采用ES模块解析规则。而Jest默认的jest.mock提升机制在ES模块环境下不生效——ES模块的import是静态解析并优先执行的,导致你导入的是真实的fs模块,而非Jest生成的模拟版本。


正确解决方法

方法1:调整jest.mock执行顺序(推荐)

在ES模块环境下,必须让jest.mock在所有import之前执行,才能覆盖真实模块的导入。修改测试代码如下:

import { jest } from '@jest/globals';

// 先调用jest.mock,再导入fs
jest.mock('fs', () => ({
  readFileSync: jest.fn().mockReturnValue('test'),
}));

// 必须在jest.mock之后导入fs
import * as fs from 'fs';

describe('mock test', () => {
  it('should read file content', () => {
    expect(fs.readFileSync('abcd.test', 'utf8')).toBe('test');
  });
});

方法2:切换到CommonJS模块规则

如果项目不需要严格使用ES模块,可以修改tsconfig配置,切换到CommonJS解析规则:

"module": "CommonJS",
"moduleResolution": "node"

此时Jest的传统jest.mock提升机制会正常工作,原测试代码无需大幅修改。

方法3:使用jest.spyOn模拟单个方法

如果只需要模拟fs的特定方法,而非替换整个模块,jest.spyOn在ES模块环境下更稳定:

import * as fs from 'fs';
import { jest } from '@jest/globals';

describe('mock test', () => {
  it('should read file content', () => {
    // 模拟readFileSync方法
    const mockReadFileSync = jest.spyOn(fs, 'readFileSync').mockReturnValue('test');
    expect(fs.readFileSync('abcd.test', 'utf8')).toBe('test');
    // 测试完成后恢复原方法
    mockReadFileSync.mockRestore();
  });
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 04:20:05