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

为什么使用Jest无法mock JavaScript的fs.readFileSync方法?

问题修复方案

核心错误原因

  • 模块初始化时机早于mock赋值:测试代码顶部先引入了./secret模块,模块加载时会立刻执行getSecret初始化secretConfig,此时fs的mock返回值还未设置,只能拿到undefined
  • 同步方法误用异步mock接口:fs.readFileSync是同步方法,第一个测试用例用了仅适配异步Promise方法的mockResolvedValue设置返回值,不生效
  • 变量覆盖:第二个测试用例内部定义了const secret = 'secret',覆盖了顶部导入的secret模块对象,访问字符串的kafka_keystore_password属性自然返回undefined

修复后的测试代码

无需修改业务代码,仅调整测试逻辑即可:

let fs = require('fs')
jest.mock('fs');

describe('secret read files', () => {
  afterEach(jest.resetModules()); // 每次测试重置模块缓存,保证重新导入时会重新初始化
  afterEach(jest.restoreAllMocks);
  it('should read secret from file', () => {
    // 先设置mock返回值,再导入模块
    fs.readFileSync.mockReturnValue("randomPrivateKey");
    const secret = require('./secret');
    const secretMessage = secret.kafka_keystore_password;
    expect(fs.readFileSync).toHaveBeenCalledWith('/etc/secrets/kafka_keystore_password.txt', 'utf8');
    expect(secretMessage).toEqual('randomPrivateKey');
  })
})

describe('getSecretsFromFile', () => {
  afterEach(jest.resetModules());
  afterEach(jest.restoreAllMocks);

  it('returns secrets if file is present', () => {
    fs.readFileSync.mockReturnValue('randomPrivateKey');
    const secret = require('./secret');
    const secretMessage = secret.kafka_keystore_password;
    expect(secretMessage).toEqual('randomPrivateKey');
  });
});

可选优化(业务代码更易测试)

如果允许调整业务代码,建议把静态导出的配置改为函数导出,避免模块加载时就执行IO操作,使用更灵活:

// 待测试文件修改后代码
const fs = require('fs');

const read_file = (path) => {
  try {
    const data = fs.readFileSync(path, 'utf8');
    return data;
  } catch (err) {
    console.error('Error in read_file', err);
    throw err;
  }
};

const getSecret = secretName => {
  try {
    return read_file(`/etc/secrets/${secretName}.txt`);
  } catch (err){
    throw err;
  }
};

// 改为函数导出,调用时才初始化
const getSecretConfig = () => ({
  kafka_keystore_password: getSecret('kafka_keystore_password')
});

module.exports = getSecretConfig;

修改后测试时不需要考虑模块导入时机,直接调用函数即可:

const getSecretConfig = require('./secret');
let fs = require('fs')
jest.mock('fs');

describe('secret read files', () => {
  afterEach(jest.restoreAllMocks);
  it('should read secret from file', () => {
    fs.readFileSync.mockReturnValue("randomPrivateKey");
    const secretConfig = getSecretConfig();
    expect(secretConfig.kafka_keystore_password).toEqual('randomPrivateKey');
  })
})

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 21:24:03