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

使用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"
  }
}

命令提示符错误信息(翻译后)

  1. 语法错误:无法在模块外使用import语句
  2. 模块查找失败:找不到'./script'模块或其类型声明文件
  3. 断言失败:预期值为指定数字,但实际拿到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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 21:58:12