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

Jest测试TS初始化WebGLRenderer时报Error creating WebGL context错误

问题根因

这个报错和你本地Chrome的WebGL硬件加速状态完全无关。Jest默认使用jsdom作为测试运行环境,jsdom是纯JavaScript实现的轻量DOM模拟,本身不提供真实的Canvas渲染、WebGL上下文创建能力,从错误堆栈里的提示Not implemented: HTMLCanvasElement.prototype.getContext (without installing the canvas npm package)就能直接确认问题:测试代码根本没有运行在你本地的真实浏览器里,自然用不上系统的WebGL能力。

解决方案

根据你的测试场景选对应方案即可:

方案1:Mock WebGL上下文(适合普通单元测试,不需要真实渲染)

这是单元测试场景最常用的方案,配置简单测试速度快:

  • 首先安装jsdom官方推荐的可选canvas依赖,补全基础Canvas API实现:
    npm install --save-dev canvas
  • 新建Jest全局初始化文件,比如命名为jest.setup.ts,写入WebGL mock逻辑,拦截getContext调用返回模拟对象:
// 拦截Canvas getContext调用,mock WebGL上下文避免初始化报错
HTMLCanvasElement.prototype.getContext = jest.fn((contextType: string) => {
  // WebGL类型上下文返回mock对象,覆盖Three.js初始化时会调用的基础方法
  if (['webgl', 'webgl2', 'experimental-webgl'].includes(contextType)) {
    return {
      createShader: jest.fn(),
      shaderSource: jest.fn(),
      compileShader: jest.fn(),
      getShaderParameter: jest.fn(() => true),
      createProgram: jest.fn(),
      attachShader: jest.fn(),
      linkProgram: jest.fn(),
      getProgramParameter: jest.fn(() => true),
      useProgram: jest.fn(),
      createBuffer: jest.fn(),
      bindBuffer: jest.fn(),
      bufferData: jest.fn(),
      viewport: jest.fn(),
      clearColor: jest.fn(),
      clear: jest.fn(),
      // 后续如果运行时报某个WebGL方法不存在,按需在这里补mock即可
    } as unknown as WebGLRenderingContext;
  }
  // 2d等其他上下文类型用canvas包提供的原生实现
  return require('canvas').createCanvas(200, 200).getContext(contextType);
});
  • 在Jest配置文件jest.config.js/jest.config.ts中引入该初始化文件:
module.exports = {
  // 其他已有配置保持不变
  testEnvironment: 'jsdom',
  setupFilesAfterEnv: ['./jest.setup.ts']
}

方案2:使用真实浏览器运行测试(适合需要真实渲染的集成/E2E测试)

如果你的测试需要验证真实的WebGL渲染效果,不要使用jsdom环境,替换为支持真实浏览器内核的测试运行器即可,比如使用jest-electron或者jest-puppeteer,测试代码会运行在真实的Chromium内核中,自带完整的WebGL支持,不需要任何mock,和本地浏览器运行效果完全一致。

方案3:直接Mock Three.js的WebGLRenderer类(纯逻辑测试最快方案)

如果你写的是纯业务逻辑单元测试,根本不需要真实的渲染器实例,只需要验证逻辑是否正确调用了渲染器初始化、参数传递是否正确,直接在测试文件顶部mock Three.js模块即可,不需要安装任何额外依赖:

jest.mock('three', () => ({
  ...jest.requireActual('three'),
  WebGLRenderer: jest.fn().mockImplementation(() => ({
    setSize: jest.fn(),
    setPixelRatio: jest.fn(),
    render: jest.fn(),
    domElement: document.createElement('canvas')
    // 按需补全你测试代码中会调用到的renderer方法即可
  }))
}));

注意:不需要浪费时间排查本地浏览器的WebGL配置、硬件加速开关,jsdom环境和你系统安装的Chrome是完全隔离的,浏览器侧的配置不会对Jest的jsdom环境产生任何影响。

内容的提问来源于stack exchange,提问作者Mohammad Humayun Khan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 11:39:38