【问题标题】:How to properly mock fs.readFileSync() in Jest?如何在 Jest 中正确模拟 fs.readFileSync()?
【发布时间】:2025-12-25 02:55:11
【问题描述】:

我正在使用 fs 模块将 html 字符串导入到我的模块中,如下所示:

const fs = require('fs');    
const htmlString = fs.readFileSync("../utils/htmlString.html").toString();

然后,在我的测试文件中,我尝试像这样模拟 fs 模块:

const fs = require('fs');
jest.mock("fs", () => {
  return {
    readFileSync: jest.fn()
  }
})
fs.readFileSync.mockReturnValue("test string");

我可能错误的逻辑告诉我它应该正确地模拟原始字符串导入并将其替换为“测试字符串”字符串。但是,在运行测试时它会抛出:

TypeError:无法读取未定义的属性“toString”

我知道这意味着模拟不成功,因为它应该成功地在字符串实例上调用 .toString()。

我在这里做错了什么?

【问题讨论】:

  • 你能显示你的jest.config.js吗?以及您如何要求要测试的模块?

标签: javascript node.js unit-testing testing jestjs


【解决方案1】:

您无需为jest.mock('fs') 显式提供模块工厂参数。 jest.mock() 在需要时使用自动模拟版本模拟模块。这意味着fs.readFileSync 是一个模拟方法,与jest.fn() 相同。

您需要确保在模拟返回值后需要被测模块,因为模块范围内的代码将在需要时立即执行。

例如

index.js:

const fs = require('fs');
const htmlString = fs.readFileSync('../utils/htmlString.html').toString();
console.log('htmlString: ', htmlString);

index.test.js:

const fs = require('fs');

jest.mock('fs');

describe('70760704', () => {
  test('should pass', () => {
    expect(jest.isMockFunction(fs.readFileSync)).toBeTruthy();
    fs.readFileSync.mockReturnValue('test string');
    require('./');
  });
});

测试结果:

 PASS  */70760704/index.test.js (7.242 s)
  70760704
    ✓ should pass (14 ms)

  console.log
    htmlString:  test string

      at Object.<anonymous> (*/70760704/index.js:3:9)

Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        7.279 s, estimated 8 s

jest.config.js:

module.exports = {
  testEnvironment: 'node',
};

软件包版本:

"jest": "^26.6.3"

【讨论】: