源代码: lib/assert.js

严格断言模式

版本 变更
v15.0.0 暴露为 require(‘assert/strict’)。
v13.9.0,
v12.16.2
将“严格模式”更改为“严格断言模式”,将“旧版模式”更改为“旧版断言模式”,以避免与“严格模式”更常见的含义混淆。
v9.9.0 添加错误差异到严格断言模式。
v9.9.0 添加严格断言模式到断言模块。
v9.9.0 新增于: v9.9.0

在严格断言模式下,非严格方法的行为与其对应的严格方法相同。
例如, assert.deepEqual() 的行为类似于 assert.deepStrictEqual() 。

在严格断言模式下,对象的错误消息显示差异。
在旧版断言模式下,对象的错误消息显示对象,通常被截断。

使用严格断言模式:

  1. // ESM
  2. import { strict as assert } from 'assert'; // 方式1
  3. import assert from 'assert/strict'; // 方式2
  4. // CJS
  5. const assert = require('assert').strict; // 方式1
  6. const assert = require('assert/strict'); // 方式2

错误差异的示例:

  1. // ESM (交互式不能使用)
  2. import { strict as assert } from 'assert';
  3. assert.deepEqual([[[1,2,3]],4,5],[[[1,2,'3']],4,5]);
  4. // CJS
  5. const assert = require('assert/strict');
  6. assert.deepEqual([[[1,2,3]],4,5],[[[1,2,'3']],4,5]);

输出应当如下图所示:
image.png
要停用颜色,则使用 NO_COLOR 或 NODE_DISABLE_COLORS 环境变量。 这也将停用交互式解释器中的颜色。 有关终端环境中颜色支持的更多信息,请阅读终端 getColorDepth() 文档。

旧版断言模式

旧版断言模式在以下方法中使用 抽象相等比较

使用旧版断言模式:

  1. // ESM
  2. import assert from 'assert';
  3. // CJS
  4. const assert = require('assert');

尽可能改用严格断言模式 ,而不是使用旧版断言模式。 否则,抽象相等比较可能会导致意外的结果。 对于 assert.deepEqual() 尤其如此,其比较规则很宽松:

  1. // 注意:这不会抛出 AssertionError
  2. assert.deepEqual(/a/gi, new Date());

assert.AssertionError 类

表示断言的失败。
assert 模块抛出的所有错误都是 AssertionError 类的实例。

new assert.AssertionError(options)

  1. const assert = require('assert');
  2. // 生成 AssertionError,以便稍后比较错误信息:
  3. const { message } = new assert.AssertionError({
  4. actual: 1,
  5. expected: 2,
  6. operator: 'strictEqual'
  7. });
  8. // 验证错误的输出:
  9. try {
  10. assert.strictEqual(1, 2);
  11. } catch (err) {
  12. assert(err instanceof assert.AssertionError);
  13. assert.strictEqual(err.message, message);
  14. assert.strictEqual(err.name, 'AssertionError');
  15. assert.strictEqual(err.actual, 1);
  16. assert.strictEqual(err.expected, 2);
  17. assert.strictEqual(err.code, 'ERR_ASSERTION');
  18. assert.strictEqual(err.operator, 'strictEqual');
  19. assert.strictEqual(err.generatedMessage, true);
  20. }

image.png

assert.CallTracker 类

new assert.CallTracker()

创建新的 CallTracker 对象, 其可用于跟踪函数是否被调用了特定次数。
必须调用 tracker.verify() 才能进行验证。通常的模式是在 process.on(‘exit’) 句柄中调用。

  1. const assert = require('assert');
  2. const tracker = new assert.CallTracker();
  3. function func() {}
  4. // callfunc() 必须在 tracker.verify() 之前恰好被调用 2 次。
  5. const callsfunc = tracker.calls(func, 2);
  6. // tracker.calls([fn][, exact]) 参数 exact <number> 默认值: 1
  7. // 这里只调用了一次,将引发异常
  8. callsfunc();
  9. // 调用 tracker.verify() 并验证是否所有 tracker.calls() 函数都已被准确调用。
  10. process.on('exit', () => {
  11. tracker.verify();
  12. });

异常信息显示,应当调用两次而实际调用一次。
image.png

assert(value[, message])

assert.ok() 的别名。

  • value 检查为真的输入。
  • message |

    assert.ok(value[, message])

  • value

  • message |

测试 value 是否为真。 相当于 assert.equal(!!value, true, message)。
如果 value 不是真值,则抛出 AssertionError,其 message 属性设置为等于 message 参数的值。 如果 message 参数为 undefined,则分配默认错误消息。 如果 message 参数是 Error 的实例,则将抛出错误而不是 AssertionError。 如果根本没有传入任何参数,则 message 将设置为字符串:’No value argument passed to assert.ok()‘。
请注意,在 repl(node.js 交互式解释器) 中,错误消息将与文件中抛出的错误消息不同!

  1. const assert = require('assert/strict');
  2. assert.ok(true);
  3. // OK
  4. assert.ok(1);
  5. // OK
  6. assert.ok();
  7. // AssertionError: No value argument passed to `assert.ok()`
  8. assert.ok(false, 'it\'s false');
  9. // AssertionError: it's false
  10. // 在交互式解释器中:
  11. assert.ok(typeof 123 === 'string');
  12. // AssertionError: false == true
  13. // 在文件中(例如 test.js):
  14. assert.ok(typeof 123 === 'string');
  15. // AssertionError: The expression evaluated to a falsy value:
  16. //
  17. // assert.ok(typeof 123 === 'string')
  18. assert.ok(false);
  19. // AssertionError: The expression evaluated to a falsy value:
  20. //
  21. // assert.ok(false)
  22. assert.ok(0);
  23. // AssertionError: The expression evaluated to a falsy value:
  24. //
  25. // assert.ok(0)

assert.fail([message])

  • message | 默认值: ‘Failed’

抛出带有提供的错误消息或默认错误消息的 AssertionError。 如果 message 参数是 Error 的实例,则将抛出错误而不是 AssertionError

assert.ifError(value)

  • value

如果 value 不是 undefined 或 null,则抛出 value。 这在回调中测试 error 参数时很有用。 堆栈跟踪包含来自传给 ifError() 的错误的所有帧,包括 ifError() 本身的潜在新帧。

  1. const assert = require('assert/strict');
  2. assert.ifError(null);
  3. // OK
  4. assert.ifError(0);
  5. // AssertionError [ERR_ASSERTION]: ifError got unwanted exception: 0
  6. assert.ifError('error');
  7. // AssertionError [ERR_ASSERTION]: ifError got unwanted exception: 'error'
  8. assert.ifError(new Error());
  9. // AssertionError [ERR_ASSERTION]: ifError got unwanted exception: Error
  10. // 创建一些随机错误帧。
  11. let err;
  12. (function errorFrame() {
  13. err = new Error('test error');
  14. })();
  15. (function ifErrorFrame() {
  16. assert.ifError(err);
  17. })();
  18. // AssertionError [ERR_ASSERTION]: ifError got unwanted exception: test error
  19. // at ifErrorFrame
  20. // at errorFrame


assert.equal(actual, expected[, message])

版本 变更
v16.0.0 在旧版断言模式下,状态从弃用更改为旧版。
v14.0.0 如果双方都是 NaN,则现在 NaN 被视为相同。

assert.notEqual(actual, expected[, message])

版本 变更
v16.0.0 在旧版断言模式下,状态从弃用更改为旧版。
v14.0.0 如果双方都是 NaN,则现在 NaN 被视为相同。

assert.deepEqual(actual, expected[, message])

版本 变更
v16.0.0 在旧版断言模式下,状态从弃用更改为旧版。
v14.0.0 如果双方都是 NaN,则现在 NaN 被视为相同。
v12.0.0 现在可以正确地比较类型标签,并且有一些小的比较调整使检查更少意外。
v9.0.0 现在可以正确地比较 Error 名称和消息。
v8.0.0 也比较 Set 和 Map 的内容。

assert.notDeepEqual(actual, expected[, message])

版本 变更
v16.0.0 在旧版断言模式下,状态从弃用更改为旧版。
v14.0.0 如果双方都是 NaN,则现在 NaN 被视为相同。
v12.0.0 现在可以正确地比较类型标签,并且有一些小的比较调整使检查更少意外。
v9.0.0 现在可以正确地比较 Error 名称和消息。
v8.0.0 也比较 Set 和 Map 的内容。

assert.deepStrictEqual(actual, expected[, message])

测试 actual 和 expected 参数之间的深度相等。 “deep”相等意味着子对象的可枚举”自有”属性也按照以下规则递归地评估。

  1. const assert = require('assert/strict');
  2. // 这失败了,因为 1 !== '1'。
  3. assert.deepStrictEqual({ a: 1 }, { a: '1' });
  4. // AssertionError: Expected inputs to be strictly deep-equal:
  5. // + actual - expected
  6. //
  7. // {
  8. // + a: 1
  9. // - a: '1'
  10. // }
  11. // 以下对象没有自有的属性
  12. const date = new Date();
  13. const object = {};
  14. const fakeDate = {};
  15. Object.setPrototypeOf(fakeDate, Date.prototype);
  16. // 不同的原型:
  17. assert.deepStrictEqual(object, fakeDate);
  18. // AssertionError: Expected inputs to be strictly deep-equal:
  19. // + actual - expected
  20. //
  21. // + {}
  22. // - Date {}
  23. // 不同的类型标签:
  24. assert.deepStrictEqual(date, fakeDate);
  25. // AssertionError: Expected inputs to be strictly deep-equal:
  26. // + actual - expected
  27. //
  28. // + 2018-04-26T00:49:08.604Z
  29. // - Date {}
  30. assert.deepStrictEqual(NaN, NaN);
  31. // OK,因为 SameValue 比较
  32. // 不同的解封装数字:
  33. assert.deepStrictEqual(new Number(1), new Number(2));
  34. // AssertionError: Expected inputs to be strictly deep-equal:
  35. // + actual - expected
  36. //
  37. // + [Number: 1]
  38. // - [Number: 2]
  39. assert.deepStrictEqual(new String('foo'), Object('foo'));
  40. // OK,因为对象和字符串在解封装时是相同的。
  41. assert.deepStrictEqual(-0, -0);
  42. // OK
  43. // 使用 SameValue 比较的不同零:
  44. assert.deepStrictEqual(0, -0);
  45. // AssertionError: Expected inputs to be strictly deep-equal:
  46. // + actual - expected
  47. //
  48. // + 0
  49. // - -0
  50. const symbol1 = Symbol();
  51. const symbol2 = Symbol();
  52. assert.deepStrictEqual({ [symbol1]: 1 }, { [symbol1]: 1 });
  53. // OK,因为它是两个对象上的相同符号。
  54. assert.deepStrictEqual({ [symbol1]: 1 }, { [symbol2]: 1 });
  55. // AssertionError [ERR_ASSERTION]: Inputs identical but not reference equal:
  56. //
  57. // {
  58. // [Symbol()]: 1
  59. // }
  60. const weakMap1 = new WeakMap();
  61. const weakMap2 = new WeakMap([[{}, {}]]);
  62. const weakMap3 = new WeakMap();
  63. weakMap3.unequal = true;
  64. assert.deepStrictEqual(weakMap1, weakMap2);
  65. // OK,因为无法比较条目
  66. // 失败,因为 weakMap3 有一个 weakMap1 不包含的属性:
  67. assert.deepStrictEqual(weakMap1, weakMap3);
  68. // AssertionError: Expected inputs to be strictly deep-equal:
  69. // + actual - expected
  70. //
  71. // WeakMap {
  72. // + [items unknown]
  73. // - [items unknown],
  74. // - unequal: true
  75. // }

assert.notDeepStrictEqual(actual, expected[, message])

  • actual
  • expected
  • message |

检验深度严格不相等。 assert.deepStrictEqual() 的相反。
如果值是深度且严格相等的,则抛出 AssertionError,其 message 属性设置为等于 message 参数的值。 如果未定义 message 参数,则分配默认错误消息。 如果 message 参数是 Error 的实例,则将抛出错误而不是 AssertionError

assert.match(string, regexp[, message])

版本 变更
v16.0.0 此 API 不再是实验的。
v13.6.0, v12.16.0 新增于: v13.6.0, v12.16.0
  • string
  • regexp
  • message |

期望 string 输入与正则表达式匹配。
如果值不匹配,或者 string 参数的类型不是 string,则抛出 AssertionError,其 message 属性设置为等于 message 参数的值。 如果未定义 message 参数,则分配默认错误消息。 如果 message 参数是 Error 的实例,则将抛出错误而不是 AssertionError

  1. const assert = require('assert/strict');
  2. assert.match('I will fail', /pass/);
  3. // AssertionError [ERR_ASSERTION]: The input did not match the regular ...
  4. assert.match(123, /pass/);
  5. // AssertionError [ERR_ASSERTION]: The "string" argument must be of type string.
  6. assert.match('I will pass', /pass/);
  7. // OK

assert.doesNotMatch(string, regexp[, message])

期望 string 输入与正则表达式(RegExp)不匹配。
如果值匹配,或者 string 参数的类型不是 string,则抛出 AssertionError,其 message 属性设置为等于 message 参数的值。 如果未定义 message 参数,则分配默认错误消息。 如果 message 参数是 Error 的实例,则将抛出错误而不是 AssertionError

  1. const assert = require('assert/strict');
  2. assert.doesNotMatch('I will fail', /fail/);
  3. // AssertionError [ERR_ASSERTION]: The input was expected to not match the ...
  4. assert.doesNotMatch(123, /pass/);
  5. // AssertionError [ERR_ASSERTION]: The "string" argument must be of type string.
  6. assert.doesNotMatch('I will pass', /different/);
  7. // OK

assert.rejects(asyncFn[, error][, message])

新增于: v10.0.0