node.js之assert学习梳理
本篇仅是个人对于assert断言学习的梳理,也希望可以给开始学习assert同学提供一个基础框架。
一、assert概念
assert模块提供了一组简单的断言测试,可用于测试不变量。
存在严格模式(strict)和 遗留模式(legacy),但建议仅使用严格模式。
二、assert.AssertionError 类
Error的子类,表明断言的失败。assert模块抛出的所有错误都是AssertionError类的实例
三、assert方法的一些规律
- equal、notEqual、deepEqual、notDeepEqual:使用’==’比较符进行比较。即:不含strict的方法,使用的都是’==’比较符。
- strictEqual、notStrictEqual、strictDeepEqual、notStrictDeepEqual:使用’===’比较符进行比较。即:含strict的方法,使用的都是’===’比较符。
- notEqual、notDeepEqual 、notStrictDeepEqual与不带Not的方法正好相反,但是使用方式完全相同。
注意:在最新的node版本中不含strict的方法已经被废弃
四、assert方法详解
- assert(value[, message])
等同于assert.ok(),用来判断一个值是否为真。若为真,则会通过该行测试;若为假,则会报错。如果没有第二个参数,则会默认报错”AssertionError: value == true”,如果第二个参数存在,则会抛出message的内容
assert(true, 'message'); //输出 undefined assert(false, 'message'); //输出 AssertionError: message
- assert.strictEqual(actual, expected, [message])
严格相等,和全等符号(===)的判断结果相同。
assert.strictEqual(1, 1, 'message'); //输出 undefined assert.strictEqual(1, '1', 'message'); //输出 AssertionError: message assert.strictEqual(1, '1', 'message'); //输出 AssertionError: message
assert.deepStrictEqual(actual, expected, [message])
测试 actual 参数和 expected 参数之间的深度相等。
1.当比较的双方均为基本类型时,等价于euqal()。
2.当比较的双方均为引用类型时,即将引用类型中的每一个属性用equal()进行比较。
比较规则使用 SameValue比较(使用 Object.is())来比较原始值。 对象的类型标签应该相同。 使用严格相等比较来比较对象的原型。 只考虑可枚举的自身属性。 始终比较 Error 的名称和消息,即使这些不是可枚举的属性。 可枚举的自身 Symbol 属性也会比较。 对象封装器作为对象和解封装后的值都进行比较。 Object 属性的比较是无序的。 Map 键名与 Set 子项的比较是无序的。 当两边的值不相同或遇到循环引用时,递归停止。
const assert = require('assert').strict; // 失败,因为 1 !== '1'。 assert.deepStrictEqual({ a: 1 }, { a: '1' }); // 以下对象没有自身属性。 const date = new Date(); const object = {}; const fakeDate = {}; Object.setPrototypeOf(fakeDate, Date.prototype); // 原型不同: assert.deepStrictEqual(object, fakeDate); // - {} // + Date {} // 类型标签不同: assert.deepStrictEqual(date, fakeDate); // - 2018-04-26T00:49:08.604Z // + Date {} assert.deepStrictEqual(NaN, NaN); // 通过,因为使用 SameValue 比较。 // 解封装后的数字不同: assert.deepStrictEqual(new Number(1), new Number(2)); // - [Number: 1] // + [Number: 2] assert.deepStrictEqual(new String('foo'), Object('foo')); // 通过,因为对象与解封装后的字符串都是相同的。 assert.deepStrictEqual(-0, -0); // 通过。 // 使用 SameValue 比较的零不同: assert.deepStrictEqual(0, -0); // - 0 // + -0 const symbol1 = Symbol(); const symbol2 = Symbol(); assert.deepStrictEqual({ [symbol1]: 1 }, { [symbol1]: 1 }); // 通过,因为在两个对象上的 symbol 相同。 assert.deepStrictEqual({ [symbol1]: 1 }, { [symbol2]: 1 }); // { // [Symbol()]: 1 // } const weakMap1 = new WeakMap(); const weakMap2 = new WeakMap([[{}, {}]]); const weakMap3 = new WeakMap(); weakMap3.unequal = true; assert.deepStrictEqual(weakMap1, weakMap2); // 通过,因为无法比较条目。 // 失败,因为 weakMap3 有一个 weakMap1 不包含的属性: assert.deepStrictEqual(weakMap1, weakMap3); // WeakMap { // - [items unknown] // + [items unknown], // + unequal: true // }
- assert.fail([message])
使用提供的错误消息或默认错误消息抛出 AssertionError。 如果 message 参数是 Error 的实例,则它将被抛出而不是 AssertionError。
const assert = require('assert').strict; assert.fail(); // AssertionError [ERR_ASSERTION]: Failed assert.fail('失败'); // AssertionError [ERR_ASSERTION]: 失败 assert.fail(new TypeError('需要数组')); // TypeError: 需要数组
- assert.ifError(value)
如果 value 不为 undefined 或 null,则抛出 value。 - assert.throws(fn, error)
期望 fn 函数抛出错误(这个方法还不是很明白)