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

如何在Jest中不修改源码Mock AudioContext解决jsdom不支持问题

Jest 环境下无侵入 mock AudioContext 方案

核心逻辑:jsdom 环境默认未挂载 AudioContext 全局属性,因此直接调用 spyOn 会因为属性为 undefined 报错。只需提前手动将 mock 的 AudioContext 构造函数挂载到全局,即可实现和 Math.random 一致的 mock 效果,全程无需修改业务源码。


单测试文件临时 mock

适合仅单个测试用例需要用到 AudioContext 的场景:

// 自定义mock AudioContext类,可根据业务需要补充方法实现
class MockAudioContext {
  constructor() {}
  // 示例:如果业务用到createOscillator方法,可在此处添加mock
  createOscillator = jest.fn(() => ({
    connect: jest.fn(),
    start: jest.fn(),
    stop: jest.fn()
  }))
}

beforeEach(() => {
  // 挂载到全局,jsdom环境也可以替换为window,用globalThis可兼容不同环境
  global.AudioContext = MockAudioContext
  // 兼容部分旧写法的webkit前缀实现
  global.webkitAudioContext = MockAudioContext
})

test('测试context为空时会新建AudioContext', () => {
  // 如果需要监听构造函数调用情况,可替换为jest.fn实现
  const mockCtxConstructor = jest.fn(() => new MockAudioContext())
  global.AudioContext = mockCtxConstructor

  // 此处调用你要测试的业务逻辑
  const newState = yourTestFunction({ context: null })

  expect(newState.context).not.toBeNull()
  expect(mockCtxConstructor).toHaveBeenCalledTimes(1)
})

afterEach(() => {
  // 清理全局挂载,避免污染其他测试用例
  delete global.AudioContext
  delete global.webkitAudioContext
})

多测试文件全局 mock

如果多个测试用例都需要用到 AudioContext,可直接配置到 Jest 全局启动文件中:

  1. 首先在 jest.config.js 中添加全局启动文件配置:
module.exports = {
  // 其余配置保持不变
  setupFiles: ['./jest.setup.js']
}
  1. 在项目根目录新建 jest.setup.js,写入全局 mock 逻辑:
class MockAudioContext {
  // 在此处统一添加所有业务用到的AudioContext方法mock
  createGain = jest.fn(() => ({
    connect: jest.fn(),
    gain: { value: 0, setValueAtTime: jest.fn() }
  }))
  decodeAudioData = jest.fn()
  resume = jest.fn().mockResolvedValue()
  suspend = jest.fn().mockResolvedValue()
  close = jest.fn().mockResolvedValue()
}

global.AudioContext = MockAudioContext
global.webkitAudioContext = MockAudioContext

配置完成后所有测试文件都可以直接使用 mock 后的 AudioContext,无需重复定义。


如果你需要对 AudioContext 做方法监听、自定义返回值等操作,也可以在挂载后正常使用 spyOn:

// 注意必须先挂载属性才能调用spyOn
global.AudioContext = jest.fn()
const audioCtxSpy = jest.spyOn(global, 'AudioContext').mockReturnValue({
  // 自定义返回的实例内容
})

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 09:45:04