使用JavaScript、Node.js和Chai做单元测试遇TypeError问题求助
计算器单元测试报错排查
项目目录结构
src/: 存储计算器核心逻辑代码test/: 存储单元测试文件package.json: 项目依赖与脚本配置文件
单元测试文件(test/calculator.test.js)
const { expect } = import('chai'); const { cos, sin, tan, sqrt, ln, exp, compute, square, checkNum } = import('./script'); describe('Trigonometric Functions', function () { it('should compute the cosine of a number', function () { const result = cos({ display: { value: 0 } }); expect(result).to.equal(1); }); it('should compute the sine of a number', function () { const result = sin({ display: { value: Math.PI / 2 } }); expect(result).to.equal(1); }); it('should compute the tangent of a number', function () { const result = tan({ display: { value: 0 } }); expect(result).to.equal(0); }); }); describe('Mathematical Functions', function () { it('should compute the square root of a number', function () { const result = sqrt({ display: { value: 16 } }); expect(result).to.equal(4); }); it('should compute the natural logarithm of a number', function () { const result = ln({ display: { value: Math.E } }); expect(result).to.equal(1); }); it('should compute the exponential of a number', function () { const result = exp({ display: { value: 2 } }); expect(result).to.equal(Math.exp(2)); }); }); describe('Computation and Validation', function () { it('should perform basic computation using eval', function () { const result = compute({ display: { value: '2 + 3' } }); expect(result).to.equal(5); }); it('should square a number', function () { const result = square({ display: { value: 4 } }); expect(result).to.equal(16); }); it('should validate numeric input', function () { const validInput = checkNum('12345'); const invalidInput = checkNum('12a345'); expect(validInput).to.be.true; expect(invalidInput).to.be.false; }); });
计算器应用代码(src/script.js)
function addChar(input, character) { if(input.value == null || input.value == "0") input.value = character else input.value += character } function cos(form) { form.display.value = Math.cos(form.display.value); } function sin(form) { form.display.value = Math.sin(form.display.value); } function tan(form) { form.display.value = Math.tan(form.display.value); } function sqrt(form) { form.display.value = Math.sqrt(form.display.value); } function ln(form) { form.display.value = Math.log(form.display.value); } function exp(form) { form.display.value = Math.exp(form.display.value); } function deleteChar(input) { input.value = input.value.substring(0, input.value.length - 1) } var val = 0.0; function percent(input) { val = input.value; input.value = input.value + "%"; } function changeSign(input) { if(input.value.substring(0, 1) == "-") input.value = input.value.substring(1, input.value.length) else input.value = "-" + input.value } function compute(form) { //if (val !== 0.0) { // var percent = form.display.value; // percent = pcent.substring(percent.indexOf("%")+1); // form.display.value = parseFloat(percent)/100 * val; //val = 0.0; // } else form.display.value = eval(form.display.value); } function square(form) { form.display.value = eval(form.display.value) * eval(form.display.value) } function checkNum(str) { for (var i = 0; i < str.length; i++) { var ch = str.charAt(i); if (ch < "0" || ch > "9") { if (ch != "/" && ch != "*" && ch != "+" && ch != "-" && ch != "." && ch != "(" && ch!= ")" && ch != "%") { alert("invalid entry!") return false } } } return true }
package.json配置
{ "name": "chai", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "mocha" }, "keywords": [], "author": "", "license": "ISC", "dependencies": { "chai": "^5.0.0", "Math": "^0.0.1-security", "mocha": "^10.2.0", "save-dev": "^0.0.1-security" } }
命令提示符错误信息(翻译后)
- 语法错误:无法在模块外使用import语句
- 模块查找失败:找不到'./script'模块或其类型声明文件
- 断言失败:预期值为指定数字,但实际拿到
undefined
问题修复步骤
1. 修正模块导入方式
项目默认使用CommonJS模块规范,需将测试文件中的动态import改为require,同时修正文件路径(测试文件在test/,需向上一级引用src/下的脚本):
const { expect } = require('chai'); const { cos, sin, tan, sqrt, ln, exp, compute, square, checkNum } = require('../src/script');
2. 导出计算器函数
在src/script.js末尾添加CommonJS导出语句,让测试文件能引入这些函数:
module.exports = { cos, sin, tan, sqrt, ln, exp, compute, square, checkNum };
3. 让函数返回计算结果
原计算器函数仅修改传入对象的属性,无返回值,导致测试断言拿到undefined。修改所有被测试的函数,返回计算结果:
示例(cos函数):
function cos(form) { const result = Math.cos(form.display.value); form.display.value = result; return result; }
同理修改sin、tan、sqrt、ln、exp、compute、square函数。
4. 修复package.json依赖配置
- 删除无效的
Math和save-dev依赖 - 将
chai、mocha移至devDependencies(开发环境依赖) - 明确测试脚本的目标目录:
{ "name": "calculator-test", "version": "1.0.0", "description": "", "main": "src/script.js", "scripts": { "test": "mocha test/" }, "keywords": [], "author": "", "license": "ISC", "devDependencies": { "chai": "^5.0.0", "mocha": "^10.2.0" } }
执行npm install重新安装依赖。
5. 移除浏览器环境API
checkNum函数中的alert在Node.js环境下无法运行,直接删除该语句:
function checkNum(str) { for (var i = 0; i < str.length; i++) { var ch = str.charAt(i); if (ch < "0" || ch > "9") { if (ch != "/" && ch != "*" && ch != "+" && ch != "-" && ch != "." && ch != "(" && ch!= ")" && ch != "%") { return false; } } } return true; }
内容的提问来源于stack exchange,提问作者Theo Blank
相关产品推荐
相关产品推荐

