使用Jasmine/Karma测试操作DOM的JS函数时遇变量未定义报错求助
解决Jasmine+Karma测试DOM操作函数的ReferenceError问题
嘿,我看了你刚接触JS单元测试时遇到的问题,用Jasmine和Karma测试setRenderer函数时出现了ReferenceError: threeD is not defined的报错,咱们一步步拆解问题并解决它~
问题根源分析
我梳理了你的代码后,发现两个关键问题:
- 变量未声明触发严格模式报错:你的
setRenderer函数里,threeD和renderer变量直接赋值但没有用let/const/var声明。Karma通常默认启用严格模式,在严格模式下,未声明的变量赋值会直接抛出ReferenceError,而不是自动创建全局变量——这就是你看到报错的核心原因。 - 测试代码的语法小错误:你的测试用例里,
expect语句多了一个左括号,虽然这不是当前报错的直接原因,但不修复的话后续也会阻碍测试执行。
修复步骤
1. 先修复setRenderer函数的变量声明
打开你的renderer.js文件,给未声明的变量加上声明:
如果threeD和renderer只是函数内部使用的变量,修改成这样:
export function setRenderer() { let threeD = document.getElementById('container'); let renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true, }); renderer.setSize(threeD.clientWidth, threeD.clientHeight); let blueColor = 0x607d8b; let alpha = 1; renderer.setClearColor(blueColor, alpha); threeD.appendChild(renderer.domElement); }
如果这两个变量需要供模块内其他函数调用,就把声明移到函数外部:
let threeD; let renderer; export function setRenderer() { threeD = document.getElementById('container'); renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true, }); // 后续代码保持不变 }
2. 修复测试代码并优化测试逻辑
修改你的测试代码,修复语法错误,同时添加测试前后的DOM环境处理,保证测试独立性:
/* globals describe, it, expect, beforeEach, afterEach*/ import {setRenderer} from '../../lessons/04/renderer'; describe('Configuration', () => { it('should true be true', () => { expect(true).toBe(true); }); }); describe('Renderer', () => { let containerDiv; beforeEach(() => { // 测试前创建container元素,顺便设置宽高避免renderer获取到0尺寸 containerDiv = document.createElement("div"); containerDiv.id = 'container'; containerDiv.style.width = '800px'; containerDiv.style.height = '600px'; document.body.appendChild(containerDiv); }); afterEach(() => { // 测试后清理DOM,避免影响其他测试用例 document.body.removeChild(containerDiv); }); it('should be created', () => { setRenderer(); // 修复语法错误:把多余的左括号去掉,正确闭合expect expect(document.getElementById('container')).toBe(containerDiv); // 还可以加个额外测试,验证renderer的canvas是否被正确添加 expect(containerDiv.children.length).toBe(1); expect(containerDiv.firstChild.tagName).toBe('CANVAS'); }); });
额外小提示
- 给测试用的container设置宽高是因为
renderer.setSize依赖元素的clientWidth和clientHeight,如果不设置,这两个值会是0,虽然不影响当前测试,但后续如果要测试renderer的尺寸,这个设置就很有必要了。 - 用
afterEach清理DOM是单元测试的最佳实践,能确保每个测试用例都在干净的环境中运行,不会互相干扰。
内容的提问来源于stack exchange,提问作者Yone
相关产品推荐
相关产品推荐

