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

如何在Jasmine中正确Mock THREE.WebGLRenderer避免WebGL上下文创建错误?

解决Jasmine中Mock THREE.WebGLRenderer无效的问题

你之前的mock方式未生效,是因为jasmine.createSpy('THREE.WebGLRenderer')仅创建了一个孤立的间谍函数,并未替换代码里实际调用的THREE.WebGLRenderer构造函数,因此仍会触发原始构造函数的WebGL上下文创建逻辑,导致报错。

以下是针对不同引入场景的修复方案:

场景1:THREE为全局对象(通过script标签引入)

直接替换全局THREE对象上的WebGLRenderer属性为间谍:

// 定义mock的renderer对象,按需添加测试所需的方法/属性
const mockRenderer = {
  setSize: jasmine.createSpy('setSize'),
  render: jasmine.createSpy('render')
};

// 替换全局THREE.WebGLRenderer为间谍
spyOn(window.THREE, 'WebGLRenderer').and.returnValue(mockRenderer);

// 执行测试逻辑
const testElement = document.createElement('div');
yourClassInstance.init(testElement);

// 断言验证
expect(window.THREE.WebGLRenderer).toHaveBeenCalledWith({antialias: true});
expect(yourClassInstance.renderer).toBe(mockRenderer);

场景2:通过ES模块引入THREE(import语法)

若代码使用import * as THREE from 'three'引入,直接替换导入对象中的WebGLRenderer:

import * as THREE from 'three';
import YourClass from './path-to-your-class';

describe('YourClass', () => {
  let mockRenderer: any;

  beforeEach(() => {
    // 初始化mock renderer
    mockRenderer = {
      setSize: jasmine.createSpy('setSize'),
      render: jasmine.createSpy('render')
    };
    // 替换THREE.WebGLRenderer为间谍
    (THREE.WebGLRenderer as jasmine.Spy) = jasmine.createSpy().and.returnValue(mockRenderer);
  });

  it('should initialize renderer correctly', () => {
    const instance = new YourClass();
    const testElement = document.createElement('div');
    instance.init(testElement);

    expect(THREE.WebGLRenderer).toHaveBeenCalledWith({antialias: true});
    expect(instance.renderer).toBe(mockRenderer);
  });
});

场景3:通过CommonJS引入THREE(require语法)

使用proxyquire工具mock整个three模块:

const proxyquire = require('proxyquire');
const mockRenderer = { setSize: jasmine.createSpy('setSize') };

// 用proxyquire加载目标类,同时mock three模块
const YourClass = proxyquire('./path-to-your-class', {
  'three': {
    WebGLRenderer: jasmine.createSpy().and.returnValue(mockRenderer)
  }
}).default;

describe('YourClass', () => {
  it('should init renderer properly', () => {
    const instance = new YourClass();
    const testElement = document.createElement('div');
    instance.init(testElement);

    expect(require('three').WebGLRenderer).toHaveBeenCalledWith({antialias: true});
    expect(instance.renderer).toBe(mockRenderer);
  });
});

核心要点:必须确保代码中实际调用的THREE.WebGLRenderer被替换为间谍函数,而非创建无关的孤立间谍。测试环境无真实WebGL上下文,需完全mock构造函数,避免触发原始实例化逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 12:37:28