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

如何在不修改原JS文件的情况下用Jest测试全局函数?

解决Jest测试未导出全局异步函数的问题

因为你的函数是通过HTML <script> 标签引入的全局函数,没有模块导出,Jest默认运行在Node环境,直接require后找不到函数。可以通过以下两种方式解决:

方案一:使用jsdom模拟浏览器环境

Jest支持切换到jsdom环境(模拟浏览器的DOM和全局对象),让全局函数自动挂载到window对象上:

  1. 配置Jest使用jsdom环境
    修改你的jest.config.js(或者在package.json的jest字段里添加配置):

    module.exports = {
      testEnvironment: 'jsdom',
      // 保留其他现有配置
    };
    
  2. 在测试文件中访问全局函数
    直接require目标JS文件,函数会自动挂载到window,即可直接调用测试:

    // 引入全局函数所在的文件,函数会挂载到window对象
    require('./library/VoiceRecordingHelper');
    
    test('uploadVoiceRecordingToBucket 应正确完成上传', async () => {
      // Mock函数依赖的全局API(比如fetch、Blob等)
      global.fetch = jest.fn().mockResolvedValue({
        ok: true,
        json: () => Promise.resolve({ uploadId: 'test-123' })
      });
    
      // 调用全局函数并传入测试参数
      const uploadResult = await window.uploadVoiceRecordingToBucket({
        recording: new Blob(['test-audio-data'], { type: 'audio/mpeg' }),
        targetBucket: 'test-storage-bucket'
      });
    
      // 断言结果符合预期
      expect(uploadResult.uploadId).toBe('test-123');
      expect(fetch).toHaveBeenCalledTimes(1);
    });
    

方案二:手动模拟全局对象(无需jsdom)

如果测试不需要完整的浏览器环境,可以手动在Node环境中创建全局对象,让函数挂载到上面:

// 手动创建window全局对象(Node环境默认无此对象)
global.window = {};

// 引入目标JS文件,函数会挂载到我们创建的window上
require('./library/VoiceRecordingHelper');

test('测试上传函数核心逻辑', async () => {
  // Mock依赖的全局方法
  global.fetch = jest.fn().mockResolvedValue({ ok: true });

  const result = await window.uploadVoiceRecordingToBucket(/* 传入测试参数 */);
  expect(result).toBeDefined();
});

注意事项

  • 如果原JS文件依赖其他全局变量(比如navigator、document),需要在测试中提前mock这些变量,避免执行报错。
  • 全程不要修改原JS文件的导出逻辑,确保和fdk框架的兼容性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 13:15:08