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

