// assertion [əˈsɜːʃn] assert [əˈsɜː]
// http://nodejs.cn/api/assert.html 当前参考版本 node v12.13.1
/*
// assert 模块抛出的所有错误都将是 AssertionError 类的实例。
new assert.AssertionError(options: {
message: string; // 如果提供,则将错误消息设置为此值。
actual: any; // 错误实例上的 actual 属性将包含此值。
expected: any; // 错误实例上的 expected 属性将包含此值。
operator: string; // 错误实例上的 operator 属性将包含此值。
stackStartFn: Function; // 如果提供,则生成的堆栈跟踪将移除所有帧直到提供的函数。
})
assert.deepEqual(actual: any, expected: any[, message:string| Error]); 已废弃,应改为 assert.deepStrictEqual()
// 深比较
// 使用抽象的相等性比较来比较原始值。
// 对象的类型标签应该相同。
// 只考虑可枚举的自身属性。
// 始终比较 Error 的名称和消息,即使这些不是可枚举的属性。
// 对象封装器作为对象和解封装后的值都进行比较。
// Object 属性的比较是无序的。
// Map 键名与 Set 子项的比较是无序的。
// 当两边的值不相同或遇到循环引用时,递归停止。
// 不测试对象的 [[Prototype]]。
// 可枚举的自身 Symbol 属性也会比较。
// WeakMap 和 WeakSet 的比较不依赖于它们的值。
// 以下示例不会抛出 AssertionError,因为抽象的相等性比较(==)会将原始类型视为相等。
// 不会抛出 AssertionError。
assert.deepEqual('+00000000', false);
const obj1 = {a: {b: 1}}; const obj2 = {a: {b: 1}}; const obj3 = Object.create(obj1);
assert.deepEqual(obj1, obj2); // 通过
// 原型会被忽略:
assert.deepEqual(obj1, obj4);
// 抛出 AssertionError: { a: { b: 1 } } deepEqual {}
assert.notDeepEqual(actual, expected[, message]) 已废弃 与assert.deepEqual结果相反 应改为 assert.notDeepStrictEqual(actual, expected[, message])
assert.strictEqual(ctual: any, expected: any[, message:string| Error]) (assert.equal 已废弃, assert.notEqual 已废弃)
// 浅比较
assert.notStrictEqual(actual, expected[, message]) 与assert.strictEqual结果相反
assert(value: any[, message:string|Error])
// assert.ok() 的别名。
检测值是否为真值
assert(0) 抛出异常
assert(typeof 123 === 'string') 抛出异常
assert.ifError(value);
如果 value 不为 undefined 或 null,则抛出 value。
assert.ifError(0); 抛出异常
assert.ifError(undefined);
assert.ifError(null);
*/
// const assert = require("assert"); // 普通模式(Legacy | 遗留模式)
/*
请注意,如果使用上面那条语句的话,抽象的相等性比较可能会导致意外的结果。 特别是对于 assert.deepEqual(),其中的比较规则是松散的:
使用 Legacy Mode 会使下面的语句不抛出错误
assert.deepEqual([[[1, 2, 3]], 4, 5], [[[1, 2, '3']], 4, 5]);
遗留模式在以下方法中使用抽象的相等性比较:
assert.deepEqual()
assert.equal()
assert.notDeepEqual()
assert.notEqual()
*/
const assert = require('assert').strict; // 使用严格模式
// 生成 AssertionError 以便稍后比较错误的消息:
const { message } = new assert.AssertionError({
// message: '666', // 写上 message就使用写上的值,不写使用预设
actual: 1,
expected: 2,
operator: 'strictEqual'
});
/*
// console.log(`测试开始`, message);
// Input A expected to strictly equal input B: 属于A应该严格等于输入B
// 下面的内容是 console.log(`测试开始`, message); 的输出内容
测试开始 Input A expected to strictly equal input B:
+ expected - actual
- 1
+ 2
*/
console.log(`测试开始========================================`);
console.log(` `)
try {
assert.deepEqual([[[1, 2, 3]], 4, 5], [[[1, 2, '3']], 4, 5]);
} catch(err) {
console.log(err);
// Input A expected to strictly deep-equal input B: 输入A应严格地深等于输入B:
// 下面是console.log(err);的内容
/*
assert.js:85
throw new AssertionError(obj);
^
AssertionError [ERR_ASSERTION]: Input A expected to strictly deep-equal input B:
+ expected - actual ... Lines skipped
[
[
...
2,
- 3
+ '3'
]
...
5
]
at Object.<anonymous> (/Users/lijunyang/project/sinon-demo/assert.js:42:8)
at Module._compile (internal/modules/cjs/loader.js:689:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:700:10)
at Module.load (internal/modules/cjs/loader.js:599:32)
at tryModuleLoad (internal/modules/cjs/loader.js:538:12)
at Function.Module._load (internal/modules/cjs/loader.js:530:3)
at Function.Module.runMain (internal/modules/cjs/loader.js:742:12)
at startup (internal/bootstrap/node.js:282:19)
at bootstrapNodeJSCore (internal/bootstrap/node.js:743:3)
*/
}
try {
assert.strictEqual(1, 2); // 断言失败会抛出异常
} catch (err) {
// console.log(err);
/* 下面是console.log(err)的输出内容
{ AssertionError [ERR_ASSERTION]: Input A expected to strictly equal input B:
+ expected - actual
- 1
+ 2
at Object.<anonymous> (/Users/lijunyang/project/sinon-demo/assert.js:39:10)
at Module._compile (internal/modules/cjs/loader.js:689:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:700:10)
at Module.load (internal/modules/cjs/loader.js:599:32)
at tryModuleLoad (internal/modules/cjs/loader.js:538:12)
at Function.Module._load (internal/modules/cjs/loader.js:530:3)
at Function.Module.runMain (internal/modules/cjs/loader.js:742:12)
at startup (internal/bootstrap/node.js:282:19)
at bootstrapNodeJSCore (internal/bootstrap/node.js:743:3)
generatedMessage: true,
name: 'AssertionError [ERR_ASSERTION]',
code: 'ERR_ASSERTION',
actual: 1,
expected: 2,
operator: 'strictEqual' }
*/
try {
assert(err instanceof assert.AssertionError); // 断言成功没有任何返回,没有任何提示
/*
assert.strictEqual(1, 2); // 断言失败会抛出异常 // 断言失败就不会执行后面的语句了
console.log('失败1')
assert.strictEqual(1, 2); // 断言失败会抛出异常
console.log('失败2')
*/
assert.strictEqual(err.message, message);
assert.strictEqual(err.actual, 1);
assert.strictEqual(err.expected, 2);
assert.strictEqual(err.code, 'ERR_ASSERTION');
assert.strictEqual(err.operator, 'strictEqual');
assert.strictEqual(err.generatedMessage, true);
assert.strictEqual(err.name, 'AssertionError [ERR_ASSERTION]');
} catch (err) {
console.log(`err`, err);
}
}
console.log(` `)
console.log(`测试结束========================================`);
/*
assert.throws(fn[, error][, message])
// 检测fn是否抛出异常
如果指定,则 error 可以是 Class、RegExp、验证函数,每个属性将被测试严格的深度相等的验证对象、或每个属性(包括不可枚举的 message 和 name 属性)将被测试严格的深度相等的错误实例。 使用对象时,还可以在对字符串属性进行验证时使用正则表达式。 请参阅下面的示例。
如果指定 message,则当 fn 调用无法抛出或错误验证失败时, message 将附加到 AssertionError 提供的消息。
assert.doesNotThrow(fn[, error: Error | <RegExp> | <Function>][, message])
断言 fn 函数不会抛出错误。
*/
const assert = require('assert').strict;
const err = new TypeError('错误值');
err.code = 404;
err.foo = 'bar';
err.info = {
nested: true,
baz: 'text'
};
err.reg = /abc/i;
// err.info.a = 2; // 使用嵌套对象需要存在所有属性。
// 当上一条语句注释时,下面的assert通过,不然不通过
assert.throws(
() => {
throw err;
},
{ // 这个是验证对象
name: 'TypeError',
message: '错误值',
info: {
nested: true,
baz: 'text',
}
// 仅测试验证对象上的属性。
// 使用嵌套对象需要存在所有属性。
// 否则验证将失败。
}
);
// 使用正则表达式验证错误属性:
assert.throws(
() => {
throw err;
},
{
// `name` 和 `message` 属性是字符串,使用正则表达式将匹配字符串。
// 如果失败,则会抛出错误。
name: /^TypeError$/,
message: /错误/,
foo: 'bar',
info: {
nested: true,
// 无法对嵌套属性使用正则表达式!
baz: 'text'
},
// `reg` 属性包含一个正则表达式,
// 并且只有当验证对象包含相同的正则表达式时,
// 它才会通过。
reg: /abc/i
}
);
try {
assert.throws(
() => {
const otherErr = new Error('未找到');
otherErr.code = 404;
throw otherErr;
},
err // 测试 `message`、 `name` 和 `code`。
);
} catch (err) {
console.log(err);
}
// 由于 `message` 和 `name` 属性不同而失败:
/* 下面是上一条语句的输出内容
AssertionError [ERR_ASSERTION]: Input A expected to strictly deep-equal input B:
+ expected - actual
Comparison {
code: 404,
- message: '未找到',
- name: 'Error'
+ foo: 'bar',
+ info: {
+ baz: 'text',
+ nested: true
+ },
+ message: '错误值',
+ name: 'TypeError',
+ reg: /abc/i
}
at Object.<anonymous> (/Users/lijunyang/project/sinon-demo/assert2.js:62:8)
at Module._compile (internal/modules/cjs/loader.js:689:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:700:10)
at Module.load (internal/modules/cjs/loader.js:599:32)
at tryModuleLoad (internal/modules/cjs/loader.js:538:12)
at Function.Module._load (internal/modules/cjs/loader.js:530:3)
at Function.Module.runMain (internal/modules/cjs/loader.js:742:12)
at startup (internal/bootstrap/node.js:282:19)
at bootstrapNodeJSCore (internal/bootstrap/node.js:743:3)
*/
// 使用构造函数验证 instanceof: 下面这条通过
assert.throws(
() => {
throw new Error('错误值');
},
Error
);
// 使用 RegExp 验证错误消息: 使用正则表达式在错误对象上运行 .toString,因此也将包含错误名称。
assert.throws(
() => {
const error = new Error('错误值');
// console.log(error.toString()); // 返回 "Error: 错误值"
throw error;
},
/^Error: 错误值$/
);
console.log("自定义测的错误验证函数=================")
console.log(` `);
// 自定义的错误验证函数:
assert.throws(
() => {
// 如果指定 message,则当 fn 调用无法抛出或错误验证失败时, message 将附加到 AssertionError 提供的消息。
// return; // 此时没有抛出异常,错误验证失败
// 上一条语句如果未注释的话,则抛出异常,异常message为 "不是期望的错误"
throw new Error('错误值');
},
(err) => {
assert(err instanceof Error);
// assert(/value/.test(err)); // 这里会抛出异常,因为正则不匹配
return false;
// 除了 `true` 之外,不建议从验证函数返回任何内容。
// 这样做会导致再次抛出捕获的错误。
// 这通常不是理想的结果。
// 抛出有关失败的特定验证的错误(如本例所示)。
return true;
},
'不是期望的错误'
);
/*
assert.rejects(asyncFn[, error][, message])
除了等待的异步性质之外,完成行为与 assert.throws() 完全相同。
assert.doesNotReject(asyncFn[, error][, message])
与rejects相反
assert.fail([message: string | message]);
使用提供的错误消息或默认错误消息抛出 AssertionError。 如果 message 参数是 Error 的实例,则它将被抛出而不是 AssertionError。
*/
const assert = require('assert').strict;
assert.rejects(
async () => {
throw new TypeError('错误值');
},
{
name: 'TypeError',
message: '错误值'
}
);
assert.rejects(
Promise.reject(new Error('错误值1')),
{
name: 'TypeError',
message: '错误值'
}
).then((res) => {
console.log('res', res);
},(err) => {
console.log('err', err); // 此时抛出异常
});
try {
assert.fail("自定义错误消息A");
} catch (err) {
console.log(err);
}
try {
assert.fail(new Error('自定义错误消息B'));
} catch (err) {
console.log(err);
}