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

如何为依赖外部函数的.mjs文件编写Jest测试?

如何测试依赖全局对象的ESM函数(无需修改原代码)

看起来你在给大型项目里的.mjs函数写Jest测试时卡壳了——原函数依赖全局的VideoList.GetCurrentVideo(),但测试环境里没有这个对象,导致返回undefined,还不能改原代码?没问题,我们可以通过Mock全局依赖的方式搞定,完全不用动项目里的原有代码,下面是具体方案:

方案1:直接Mock全局的VideoList对象

在测试文件里,我们可以在测试前后创建并清理全局的VideoList对象,同时Mock它的方法来模拟返回值:

// 替换成你实际的模块导入路径
import { getCurrentVideo } from '../path-to-your-module.mjs';

describe('getCurrentVideo', () => {
  // 每个测试前初始化全局Mock对象
  beforeEach(() => {
    global.VideoList = {
      GetCurrentVideo: jest.fn() // 把这个方法变成Jest的Mock函数
    };
  });

  // 每个测试后清理,避免影响其他测试用例
  afterEach(() => {
    delete global.VideoList;
    jest.clearAllMocks();
  });

  test('返回拼接后的正确视频字符串', () => {
    // 模拟GetCurrentVideo的返回值
    const mockVideo = 'my-test-video-123';
    global.VideoList.GetCurrentVideo.mockReturnValue(mockVideo);

    const result = getCurrentVideo();
    // 验证返回结果是否符合预期
    expect(result).toBe(`This is the video:${mockVideo}`);
    // 还能验证原函数确实调用了这个方法
    expect(global.VideoList.GetCurrentVideo).toHaveBeenCalledTimes(1);
  });
});

方案2:如果VideoList是可导入模块,用jest.mockMock整个模块

如果VideoList本身是一个项目里的模块(而不是挂在全局的对象),那我们可以直接用Jest的jest.mock来Mock整个模块:

假设VideoList的文件路径是./VideoList.mjs,原模块代码大概是这样:

// ./VideoList.mjs
export function GetCurrentVideo() {
  // 项目里的原实现
}

那测试文件可以这么写:

import { getCurrentVideo } from '../path-to-your-module.mjs';
import * as VideoList from '../VideoList.mjs';

// Mock整个VideoList模块,替换成我们的Mock函数
jest.mock('../VideoList.mjs', () => ({
  GetCurrentVideo: jest.fn()
}));

describe('getCurrentVideo', () => {
  test('返回正确的视频拼接字符串', () => {
    const mockVideo = 'another-test-video-456';
    VideoList.GetCurrentVideo.mockReturnValue(mockVideo);

    const result = getCurrentVideo();
    expect(result).toBe(`This is the video:${mockVideo}`);
    expect(VideoList.GetCurrentVideo).toHaveBeenCalledTimes(1);
  });
});

注意事项

  • 测试独立性:一定要在afterEach里清理全局对象或者重置Mock函数,不然一个测试的Mock会影响其他测试的结果。
  • ESM配置:Jest处理ESM需要确保你的jest.config.js里有正确配置,比如设置extensionsToTreatAsEsm: ['.mjs'],或者运行测试时加上--experimental-vm-modules标志(具体看Jest版本)。
  • 无需修改原代码:这种Mock方式完全是在测试环境里做的,不会碰项目里的任何原有代码,完美符合你不能改原函数的需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 09:12:34