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

Jest中如何resolve被mock回调函数返回的Promise

问题根源

执行jest.mock('fs')后,Jest会自动对fs模块做全量mock:模块下所有方法都会被替换为默认返回undefined的空函数,不会执行任何原有逻辑。
你的代码里fs.readFile被mock后,完全不会调用你传入的回调函数,导致loadData返回的Promise一直处于pending状态,测试等不到resolve/reject结果就会触发超时。
另外你写的loadData本身存在逻辑漏洞:当fs.readFile返回err触发reject(err)后,没有加return终止后续逻辑执行,会继续往下走data解析流程,容易抛出意料之外的错误。

修复方案

1. 修正业务代码逻辑漏洞

先给loadData里两处reject之后加上return,阻断后续逻辑执行:

const fs = require('fs');
const path = require('path');

function loadData(fileName){
    let promise = new Promise((resolve, reject) => {
        fs.readFile(path.join(__dirname, `/${fileName}`), (err, data) => {
            if (err) {
              console.error(err)
              reject(err);
              return;
            }
            data = data.toString();
            try{
                data = JSON.parse(data);
            }
            catch(err){
                console.error(err)
                reject(new Error('Error while parsing json'))
                return;
            }
            resolve(data);
        })
    })
    return promise;
}

module.exports = { loadData };

2. 给mock的fs.readFile自定义实现

自动生成的空mock不会触发回调,你需要手动编写mock实现,在readFile被调用时主动执行传入的回调函数,传入模拟的错误或文件数据,驱动Promise走完状态流转:

jest.mock('fs');

const fs = require('fs');
const DI = require('./../data/data_interface');


describe('data loading functionality',() => {
    test('load data opens file system',async () => {
        expect.assertions(1);
        const testFileName = 'expenses.json';
        // 模拟文件内容
        const mockFileContent = JSON.stringify({ expenses: [] });
        // 自定义readFile mock逻辑
        fs.readFile.mockImplementation((filePath, callback) => {
            // 第一个参数传null代表无读取错误,第二个参数传模拟的文件Buffer数据
            callback(null, Buffer.from(mockFileContent));
        });

        await DI.loadData(testFileName);
        // 验证readFile被调用了1次
        expect(fs.readFile.mock.calls.length).toBe(1);
    })
})

其他测试场景的mock写法

你可以通过调整mockImplementation里传给回调的参数,覆盖不同的异常分支:

  • 测试文件读取失败场景:给回调传入错误对象作为第一个参数,比如callback(new Error('file not found'), null),此时Promise会走读文件失败的reject逻辑
  • 测试JSON解析失败场景:给回调传入非JSON格式的Buffer作为第二个参数,比如callback(null, Buffer.from('invalid json content')),此时会触发JSON解析错误的reject逻辑

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 18:48:53