在JavaScript中使用assert校验NaN:assert.deepstrictEqual测试不通过
问题分析与解决方案
首先得明确一个JavaScript的核心特性:NaN和任何值都不相等,包括它自己,这就是你用assert.deepstrictEqual断言结果为NaN时永远无法通过的原因——deepstrictEqual会做严格相等对比,而NaN === NaN的结果是false。
先拆解你的函数逻辑
你的howManyServings函数会在这些场景下返回NaN:
inventory或recipe里的某个属性(比如bread)不存在,访问不存在的属性得到undefined,Math.floor(undefined)会返回NaN- 这些属性的值不是数字类型(比如字符串、null),经过
Math.floor处理后也会变成NaN - 只要
bread_confirm/peanutButter_confirm/jam_confirm中有一个是NaN,Math.min就会直接返回NaN
正确的测试写法
要断言结果是NaN,你需要用Number.isNaN()来做类型检查,配合断言库的ok方法:
const assert = require('assert'); // 模拟会返回NaN的测试场景 const testParams = { recipe: { bread: 2, peanutButter: 1, jam: 1 }, inventory: { bread: 'not a number', peanutButter: 5, jam: 5 } // bread是字符串,会触发NaN }; const result = howManyServings(testParams); assert.ok(Number.isNaN(result), '计算结果应为NaN');
额外优化:给函数加边界校验
如果想避免意外返回NaN,可以在函数里先做参数合法性校验,让错误更明确:
function howManyServings (params) { const {recipe, inventory} = params; // 校验必要属性是否存在且为有效数字 const requiredKeys = ['bread', 'peanutButter', 'jam']; for (const key of requiredKeys) { if (typeof recipe[key] !== 'number' || typeof inventory[key] !== 'number') { throw new Error(`属性${key}必须是数字类型`); } if (recipe[key] <= 0 || inventory[key] < 0) { throw new Error(`属性${key}必须是正数`); } } const bread_confirm = Math.floor(inventory.bread / recipe.bread); const peanutButter_confirm = Math.floor(inventory.peanutButter / recipe.peanutButter); const jam_confirm = Math.floor(inventory.jam / recipe.jam); const minimum_servings = Math.min(bread_confirm, peanutButter_confirm, jam_confirm); return minimum_servings; }
这样非法参数会直接抛出明确错误,你还可以用assert.throws来测试异常场景,比断言NaN的可读性更高。
内容的提问来源于stack exchange,提问作者Amon
相关产品推荐
相关产品推荐

