Node.js v18.20.8 文档


断言#>

【Assert】

源代码: lib/assert.js

node:assert 模块提供了一组用于验证不变量的断言函数。

【The node:assert module provides a set of assertion functions for verifying invariants.】

严格断言模式#>

【Strict assertion mode】

在严格断言模式下,非严格方法的行为就像它们对应的严格方法。例如,assert.deepEqual() 的行为将像 assert.deepStrictEqual() 一样。

【In strict assertion mode, non-strict methods behave like their corresponding strict methods. For example, assert.deepEqual() will behave like assert.deepStrictEqual().】

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

【In strict assertion mode, error messages for objects display a diff. In legacy assertion mode, error messages for objects display the objects, often truncated.】

使用严格断言模式:

【To use strict assertion mode:】

import { strict as assert } from 'node:assert';const assert = require('node:assert').strict;
import assert from 'node:assert/strict';const assert = require('node:assert/strict');

错误差异的示例:

【Example error diff:】

import { strict as assert } from 'node:assert';

assert.deepEqual([[[1, 2, 3]], 4, 5], [[[1, 2, '3']], 4, 5]);
// AssertionError: Expected inputs to be strictly deep-equal:
// + actual - expected ... Lines skipped
//
//   [
//     [
// ...
//       2,
// +     3
// -     '3'
//     ],
// ...
//     5
//   ]const assert = require('node:assert/strict');

assert.deepEqual([[[1, 2, 3]], 4, 5], [[[1, 2, '3']], 4, 5]);
// AssertionError: Expected inputs to be strictly deep-equal:
// + actual - expected ... Lines skipped
//
//   [
//     [
// ...
//       2,
// +     3
// -     '3'
//     ],
// ...
//     5
//   ]

要停用颜色,请使用 NO_COLORNODE_DISABLE_COLORS 环境变量。这也会在 REPL 中停用颜色。有关终端环境中颜色支持的更多信息,请阅读 tty getColorDepth() 文档。

【To deactivate the colors, use the NO_COLOR or NODE_DISABLE_COLORS environment variables. This will also deactivate the colors in the REPL. For more on color support in terminal environments, read the tty getColorDepth() documentation.】

旧版断言模式#>

【Legacy assertion mode】

传统断言模式在以下情况下使用 == 运算符

【Legacy assertion mode uses the == operator in:】

要使用旧版断言模式:

【To use legacy assertion mode:】

import assert from 'node:assert';const assert = require('node:assert');

旧版断言模式可能会产生意想不到的结果,尤其是在使用 assert.deepEqual() 时:

【Legacy assertion mode may have surprising results, especially when using assert.deepEqual():】

// WARNING: This does not throw an AssertionError in legacy assertion mode!
assert.deepEqual(/a/gi, new Date()); 

类:assert.AssertionError#>

【Class: assert.AssertionError】

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

【Indicates the failure of an assertion. All errors thrown by the node:assert module will be instances of the AssertionError class.】

new assert.AssertionError(options)#>

  • options <Object>
    • message <string> 如果提供,此错误消息将设置为该值。
    • actual <any> 错误实例上的 actual 属性。
    • expected <any> 错误实例上的 expected 属性。
    • operator <string> 错误实例上的 operator 属性。
    • stackStartFn <Function> 如果提供,生成的堆栈跟踪会省略此函数之前的帧。

Error 的一个子类,表示断言失败。

【A subclass of Error that indicates the failure of an assertion.】

所有实例都包含内置的 Error 属性(messagename)以及:

【All instances contain the built-in Error properties (message and name) and:】

  • actual <any> 设置为方法(如 assert.strictEqual())的 actual 参数。
  • expected <any> 设置为方法(如 assert.strictEqual())的 expected 值。
  • generatedMessage <boolean> 指示消息是否为自动生成(true)或非自动生成。
  • code <string> 值始终为 ERR_ASSERTION,表示错误是断言错误。
  • operator <string> 设置为传入的运算符值。
import assert from 'node:assert';

// Generate an AssertionError to compare the error message later:
const { message } = new assert.AssertionError({
  actual: 1,
  expected: 2,
  operator: 'strictEqual',
});

// Verify error output:
try {
  assert.strictEqual(1, 2);
} catch (err) {
  assert(err instanceof assert.AssertionError);
  assert.strictEqual(err.message, message);
  assert.strictEqual(err.name, 'AssertionError');
  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);
}const assert = require('node:assert');

// Generate an AssertionError to compare the error message later:
const { message } = new assert.AssertionError({
  actual: 1,
  expected: 2,
  operator: 'strictEqual',
});

// Verify error output:
try {
  assert.strictEqual(1, 2);
} catch (err) {
  assert(err instanceof assert.AssertionError);
  assert.strictEqual(err.message, message);
  assert.strictEqual(err.name, 'AssertionError');
  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.CallTracker#>

【Class: assert.CallTracker

稳定性: 1 - 实验性

此功能目前处于实验阶段,行为可能仍会发生变化。

【This feature is currently experimental and behavior might still change.】

new assert.CallTracker()#>

创建一个新的 CallTracker 对象,可用于跟踪函数是否被调用了指定次数。必须调用 tracker.verify() 才能执行验证。通常的做法是在 process.on('exit') 处理程序中调用它。

【Creates a new CallTracker object which can be used to track if functions were called a specific number of times. The tracker.verify() must be called for the verification to take place. The usual pattern would be to call it in a process.on('exit') handler.】

import assert from 'node:assert';
import process from 'node:process';

const tracker = new assert.CallTracker();

function func() {}

// callsfunc() must be called exactly 1 time before tracker.verify().
const callsfunc = tracker.calls(func, 1);

callsfunc();

// Calls tracker.verify() and verifies if all tracker.calls() functions have
// been called exact times.
process.on('exit', () => {
  tracker.verify();
});const assert = require('node:assert');

const tracker = new assert.CallTracker();

function func() {}

// callsfunc() must be called exactly 1 time before tracker.verify().
const callsfunc = tracker.calls(func, 1);

callsfunc();

// Calls tracker.verify() and verifies if all tracker.calls() functions have
// been called exact times.
process.on('exit', () => {
  tracker.verify();
});

tracker.calls([fn][, exact])#>

封装函数预期会被调用正好 exact 次。如果在 tracker.verify() 被调用时函数并没有被正好调用 exact 次,则 tracker.verify() 将抛出一个错误。

【The wrapper function is expected to be called exactly exact times. If the function has not been called exactly exact times when tracker.verify() is called, then tracker.verify() will throw an error.】

import assert from 'node:assert';

// Creates call tracker.
const tracker = new assert.CallTracker();

function func() {}

// Returns a function that wraps func() that must be called exact times
// before tracker.verify().
const callsfunc = tracker.calls(func);const assert = require('node:assert');

// Creates call tracker.
const tracker = new assert.CallTracker();

function func() {}

// Returns a function that wraps func() that must be called exact times
// before tracker.verify().
const callsfunc = tracker.calls(func);

tracker.getCalls(fn)#>

import assert from 'node:assert';

const tracker = new assert.CallTracker();

function func() {}
const callsfunc = tracker.calls(func);
callsfunc(1, 2, 3);

assert.deepStrictEqual(tracker.getCalls(callsfunc),
                       [{ thisArg: undefined, arguments: [1, 2, 3] }]);const assert = require('node:assert');

// Creates call tracker.
const tracker = new assert.CallTracker();

function func() {}
const callsfunc = tracker.calls(func);
callsfunc(1, 2, 3);

assert.deepStrictEqual(tracker.getCalls(callsfunc),
                       [{ thisArg: undefined, arguments: [1, 2, 3] }]);

tracker.report()#>

这些数组包含了有关未按预期次数被调用的函数的预期和实际调用次数的信息。

【The arrays contains information about the expected and actual number of calls of the functions that have not been called the expected number of times.】

import assert from 'node:assert';

// Creates call tracker.
const tracker = new assert.CallTracker();

function func() {}

// Returns a function that wraps func() that must be called exact times
// before tracker.verify().
const callsfunc = tracker.calls(func, 2);

// Returns an array containing information on callsfunc()
console.log(tracker.report());
// [
//  {
//    message: 'Expected the func function to be executed 2 time(s) but was
//    executed 0 time(s).',
//    actual: 0,
//    expected: 2,
//    operator: 'func',
//    stack: stack trace
//  }
// ]const assert = require('node:assert');

// Creates call tracker.
const tracker = new assert.CallTracker();

function func() {}

// Returns a function that wraps func() that must be called exact times
// before tracker.verify().
const callsfunc = tracker.calls(func, 2);

// Returns an array containing information on callsfunc()
console.log(tracker.report());
// [
//  {
//    message: 'Expected the func function to be executed 2 time(s) but was
//    executed 0 time(s).',
//    actual: 0,
//    expected: 2,
//    operator: 'func',
//    stack: stack trace
//  }
// ]

tracker.reset([fn])#>

  • fn <Function> 一个用于重置的跟踪函数。

重置调用跟踪器的调用次数。 如果跟踪的函数作为参数传递,它的调用次数将被重置。 如果没有传递参数,所有被跟踪的函数将被重置。

【Reset calls of the call tracker. If a tracked function is passed as an argument, the calls will be reset for it. If no arguments are passed, all tracked functions will be reset】

import assert from 'node:assert';

const tracker = new assert.CallTracker();

function func() {}
const callsfunc = tracker.calls(func);

callsfunc();
// Tracker was called once
assert.strictEqual(tracker.getCalls(callsfunc).length, 1);

tracker.reset(callsfunc);
assert.strictEqual(tracker.getCalls(callsfunc).length, 0);const assert = require('node:assert');

const tracker = new assert.CallTracker();

function func() {}
const callsfunc = tracker.calls(func);

callsfunc();
// Tracker was called once
assert.strictEqual(tracker.getCalls(callsfunc).length, 1);

tracker.reset(callsfunc);
assert.strictEqual(tracker.getCalls(callsfunc).length, 0);

tracker.verify()#>

遍历传递给 tracker.calls() 的函数列表,并且对于未按预期调用次数调用的函数将抛出错误。

【Iterates through the list of functions passed to tracker.calls() and will throw an error for functions that have not been called the expected number of times.】

import assert from 'node:assert';

// Creates call tracker.
const tracker = new assert.CallTracker();

function func() {}

// Returns a function that wraps func() that must be called exact times
// before tracker.verify().
const callsfunc = tracker.calls(func, 2);

callsfunc();

// Will throw an error since callsfunc() was only called once.
tracker.verify();const assert = require('node:assert');

// Creates call tracker.
const tracker = new assert.CallTracker();

function func() {}

// Returns a function that wraps func() that must be called exact times
// before tracker.verify().
const callsfunc = tracker.calls(func, 2);

callsfunc();

// Will throw an error since callsfunc() was only called once.
tracker.verify();

assert(value[, message])#>

assert.ok() 的别名。

【An alias of assert.ok().】

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

严格断言模式

assert.deepStrictEqual() 的别名。

【An alias of assert.deepStrictEqual().】

遗留断言模式

actualexpected 参数进行深度相等性测试。考虑改用 assert.deepStrictEqual()assert.deepEqual() 可能会有意想不到的结果。

【Tests for deep equality between the actual and expected parameters. Consider using assert.deepStrictEqual() instead. assert.deepEqual() can have surprising results.】

“深度相等”意味着子对象的可枚举“自身”属性也会按照以下规则递归地进行评估。

Deep equality means that the enumerable "own" properties of child objects are also recursively evaluated by the following rules.】

比较详情#>

【Comparison details】

  • 原始值使用 == 运算符 进行比较,NaN 除外。如果两边都是 NaN,则视为相同。
  • 对象的 类型标签 应该相同。
  • 仅考虑 可枚举的“自有”属性
  • Error 的名称和信息始终进行比较,即使这些不是可枚举属性。
  • 对象封装器 既作为对象也作为解包值进行比较。
  • Object 属性以无序方式比较。
  • Map 键和 Set 项目以无序方式比较。
  • 当两边不同或都遇到循环引用时,递归停止。
  • 实现不会测试对象的 [[Prototype]]
  • Symbol 属性不进行比较。
  • WeakMapWeakSet 的比较不依赖于它们的值。
  • RegExp 的 lastIndex、flags 和 source 始终进行比较,即使这些不是可枚举属性。

以下示例不会抛出 AssertionError,因为使用 == 运算符 比较了原始类型。

【The following example does not throw an AssertionError because the primitives are compared using the == operator.】

import assert from 'node:assert';
// WARNING: This does not throw an AssertionError!

assert.deepEqual('+00000000', false);const assert = require('node:assert');
// WARNING: This does not throw an AssertionError!

assert.deepEqual('+00000000', false);

“深层”平等意味着还会对子对象的可枚举“自身”属性进行评估:

import assert from 'node:assert';

const obj1 = {
  a: {
    b: 1,
  },
};
const obj2 = {
  a: {
    b: 2,
  },
};
const obj3 = {
  a: {
    b: 1,
  },
};
const obj4 = Object.create(obj1);

assert.deepEqual(obj1, obj1);
// OK

// Values of b are different:
assert.deepEqual(obj1, obj2);
// AssertionError: { a: { b: 1 } } deepEqual { a: { b: 2 } }

assert.deepEqual(obj1, obj3);
// OK

// Prototypes are ignored:
assert.deepEqual(obj1, obj4);
// AssertionError: { a: { b: 1 } } deepEqual {}const assert = require('node:assert');

const obj1 = {
  a: {
    b: 1,
  },
};
const obj2 = {
  a: {
    b: 2,
  },
};
const obj3 = {
  a: {
    b: 1,
  },
};
const obj4 = Object.create(obj1);

assert.deepEqual(obj1, obj1);
// OK

// Values of b are different:
assert.deepEqual(obj1, obj2);
// AssertionError: { a: { b: 1 } } deepEqual { a: { b: 2 } }

assert.deepEqual(obj1, obj3);
// OK

// Prototypes are ignored:
assert.deepEqual(obj1, obj4);
// AssertionError: { a: { b: 1 } } deepEqual {}

如果值不相等,则会抛出一个 AssertionError,并且其 message 属性设置为 message 参数的值。如果 message 参数未定义,则会分配默认的错误消息。如果 message 参数是 Error 的实例,则会抛出该实例,而不是 AssertionError

【If the values are not equal, an AssertionError is thrown with a message property set equal to the value of the message parameter. If the message parameter is undefined, a default error message is assigned. If the message parameter is an instance of an Error then it will be thrown instead of the AssertionError.】

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

测试 actualexpected 参数之间的深度相等性。 “深度”相等意味着子对象的可枚举“自身”属性也会按照以下规则递归地进行评估。

【Tests for deep equality between the actual and expected parameters. "Deep" equality means that the enumerable "own" properties of child objects are recursively evaluated also by the following rules.】

比较详情#>

【Comparison details】

  • 原始值使用 Object.is() 进行比较。
  • 对象的 类型标签 应该相同。
  • 对象的 [[Prototype]] 使用 === 运算符 进行比较。
  • 仅考虑 可枚举的“自有”属性
  • Error 的名称和消息总是进行比较,即使它们不是可枚举属性。
  • 可枚举的自身 Symbol 属性也会进行比较。
  • 对象封装器 既作为对象又作为解封装值进行比较。
  • Object 的属性无序比较。
  • Map 键和 Set 项无序比较。
  • 当双方不同或双方遇到循环引用时,递归停止。
  • WeakMapWeakSet 的比较不依赖它们的值。更多细节见下文。
  • RegExp 的 lastIndex、flags 和 source 总是进行比较,即使它们不是可枚举属性。
import assert from 'node:assert/strict';

// This fails because 1 !== '1'.
assert.deepStrictEqual({ a: 1 }, { a: '1' });
// AssertionError: Expected inputs to be strictly deep-equal:
// + actual - expected
//
//   {
// +   a: 1
// -   a: '1'
//   }

// The following objects don't have own properties
const date = new Date();
const object = {};
const fakeDate = {};
Object.setPrototypeOf(fakeDate, Date.prototype);

// Different [[Prototype]]:
assert.deepStrictEqual(object, fakeDate);
// AssertionError: Expected inputs to be strictly deep-equal:
// + actual - expected
//
// + {}
// - Date {}

// Different type tags:
assert.deepStrictEqual(date, fakeDate);
// AssertionError: Expected inputs to be strictly deep-equal:
// + actual - expected
//
// + 2018-04-26T00:49:08.604Z
// - Date {}

assert.deepStrictEqual(NaN, NaN);
// OK because Object.is(NaN, NaN) is true.

// Different unwrapped numbers:
assert.deepStrictEqual(new Number(1), new Number(2));
// AssertionError: Expected inputs to be strictly deep-equal:
// + actual - expected
//
// + [Number: 1]
// - [Number: 2]

assert.deepStrictEqual(new String('foo'), Object('foo'));
// OK because the object and the string are identical when unwrapped.

assert.deepStrictEqual(-0, -0);
// OK

// Different zeros:
assert.deepStrictEqual(0, -0);
// AssertionError: Expected inputs to be strictly deep-equal:
// + actual - expected
//
// + 0
// - -0

const symbol1 = Symbol();
const symbol2 = Symbol();
assert.deepStrictEqual({ [symbol1]: 1 }, { [symbol1]: 1 });
// OK, because it is the same symbol on both objects.

assert.deepStrictEqual({ [symbol1]: 1 }, { [symbol2]: 1 });
// AssertionError [ERR_ASSERTION]: Inputs identical but not reference equal:
//
// {
//   [Symbol()]: 1
// }

const weakMap1 = new WeakMap();
const weakMap2 = new WeakMap([[{}, {}]]);
const weakMap3 = new WeakMap();
weakMap3.unequal = true;

assert.deepStrictEqual(weakMap1, weakMap2);
// OK, because it is impossible to compare the entries

// Fails because weakMap3 has a property that weakMap1 does not contain:
assert.deepStrictEqual(weakMap1, weakMap3);
// AssertionError: Expected inputs to be strictly deep-equal:
// + actual - expected
//
//   WeakMap {
// +   [items unknown]
// -   [items unknown],
// -   unequal: true
//   }const assert = require('node:assert/strict');

// This fails because 1 !== '1'.
assert.deepStrictEqual({ a: 1 }, { a: '1' });
// AssertionError: Expected inputs to be strictly deep-equal:
// + actual - expected
//
//   {
// +   a: 1
// -   a: '1'
//   }

// The following objects don't have own properties
const date = new Date();
const object = {};
const fakeDate = {};
Object.setPrototypeOf(fakeDate, Date.prototype);

// Different [[Prototype]]:
assert.deepStrictEqual(object, fakeDate);
// AssertionError: Expected inputs to be strictly deep-equal:
// + actual - expected
//
// + {}
// - Date {}

// Different type tags:
assert.deepStrictEqual(date, fakeDate);
// AssertionError: Expected inputs to be strictly deep-equal:
// + actual - expected
//
// + 2018-04-26T00:49:08.604Z
// - Date {}

assert.deepStrictEqual(NaN, NaN);
// OK because Object.is(NaN, NaN) is true.

// Different unwrapped numbers:
assert.deepStrictEqual(new Number(1), new Number(2));
// AssertionError: Expected inputs to be strictly deep-equal:
// + actual - expected
//
// + [Number: 1]
// - [Number: 2]

assert.deepStrictEqual(new String('foo'), Object('foo'));
// OK because the object and the string are identical when unwrapped.

assert.deepStrictEqual(-0, -0);
// OK

// Different zeros:
assert.deepStrictEqual(0, -0);
// AssertionError: Expected inputs to be strictly deep-equal:
// + actual - expected
//
// + 0
// - -0

const symbol1 = Symbol();
const symbol2 = Symbol();
assert.deepStrictEqual({ [symbol1]: 1 }, { [symbol1]: 1 });
// OK, because it is the same symbol on both objects.

assert.deepStrictEqual({ [symbol1]: 1 }, { [symbol2]: 1 });
// AssertionError [ERR_ASSERTION]: Inputs identical but not reference equal:
//
// {
//   [Symbol()]: 1
// }

const weakMap1 = new WeakMap();
const weakMap2 = new WeakMap([[{}, {}]]);
const weakMap3 = new WeakMap();
weakMap3.unequal = true;

assert.deepStrictEqual(weakMap1, weakMap2);
// OK, because it is impossible to compare the entries

// Fails because weakMap3 has a property that weakMap1 does not contain:
assert.deepStrictEqual(weakMap1, weakMap3);
// AssertionError: Expected inputs to be strictly deep-equal:
// + actual - expected
//
//   WeakMap {
// +   [items unknown]
// -   [items unknown],
// -   unequal: true
//   }

如果值不相等,将抛出一个 AssertionErrormessage 属性被设置为 message 参数的值。如果 message 参数未定义,则会分配默认的错误消息。如果 message 参数是 Error 的实例,则会抛出该实例,而不是 AssertionError

【If the values are not equal, an AssertionError is thrown with a message property set equal to the value of the message parameter. If the message parameter is undefined, a default error message is assigned. If the message parameter is an instance of an Error then it will be thrown instead of the AssertionError.】

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

期望 string 输入不匹配正则表达式。

【Expects the string input not to match the regular expression.】

import assert from 'node:assert/strict';

assert.doesNotMatch('I will fail', /fail/);
// AssertionError [ERR_ASSERTION]: The input was expected to not match the ...

assert.doesNotMatch(123, /pass/);
// AssertionError [ERR_ASSERTION]: The "string" argument must be of type string.

assert.doesNotMatch('I will pass', /different/);
// OKconst assert = require('node:assert/strict');

assert.doesNotMatch('I will fail', /fail/);
// AssertionError [ERR_ASSERTION]: The input was expected to not match the ...

assert.doesNotMatch(123, /pass/);
// AssertionError [ERR_ASSERTION]: The "string" argument must be of type string.

assert.doesNotMatch('I will pass', /different/);
// OK

如果值匹配,或者 string 参数的类型不是 string,将抛出一个 AssertionError,其 message 属性被设置为 message 参数的值。如果 message 参数未定义,则会分配一个默认的错误消息。如果 message 参数是 Error 的实例,则会抛出该实例而不是 AssertionError

【If the values do match, or if the string argument is of another type than string, an AssertionError is thrown with a message property set equal to the value of the message parameter. If the message parameter is undefined, a default error message is assigned. If the message parameter is an instance of an Error then it will be thrown instead of the AssertionError.】

assert.doesNotReject(asyncFn[, error][, message])#>

等待 asyncFn 的 promise,或者如果 asyncFn 是一个函数,则立即调用该函数并等待返回的 promise 完成。然后,它会检查该 promise 是否未被拒绝。

【Awaits the asyncFn promise or, if asyncFn is a function, immediately calls the function and awaits the returned promise to complete. It will then check that the promise is not rejected.】

如果 asyncFn 是一个函数并且同步抛出错误,assert.doesNotReject() 将返回一个带有该错误的被拒绝的 Promise。如果函数不返回 Promise,assert.doesNotReject() 将返回一个带有 ERR_INVALID_RETURN_VALUE 错误的被拒绝的 Promise。在这两种情况下,错误处理程序将被跳过。

【If asyncFn is a function and it throws an error synchronously, assert.doesNotReject() will return a rejected Promise with that error. If the function does not return a promise, assert.doesNotReject() will return a rejected Promise with an ERR_INVALID_RETURN_VALUE error. In both cases the error handler is skipped.】

实际上使用 assert.doesNotReject() 并没有什么用,因为捕获一个拒绝然后再次拒绝几乎没有任何好处。相反,可以考虑在不应拒绝的特定代码路径旁边添加注释,并尽量保持错误信息的表达性。

【Using assert.doesNotReject() is actually not useful because there is little benefit in catching a rejection and then rejecting it again. Instead, consider adding a comment next to the specific code path that should not reject and keep error messages as expressive as possible.】

如果指定,error 可以是 ClassRegExp 或验证函数。更多详情请参见 assert.throws()

【If specified, error can be a Class, RegExp, or a validation function. See assert.throws() for more details.】

除了异步性质需要等待完成外,其行为与 assert.doesNotThrow() 完全相同。

【Besides the async nature to await the completion behaves identically to assert.doesNotThrow().】

import assert from 'node:assert/strict';

await assert.doesNotReject(
  async () => {
    throw new TypeError('Wrong value');
  },
  SyntaxError,
);const assert = require('node:assert/strict');

(async () => {
  await assert.doesNotReject(
    async () => {
      throw new TypeError('Wrong value');
    },
    SyntaxError,
  );
})();
import assert from 'node:assert/strict';

assert.doesNotReject(Promise.reject(new TypeError('Wrong value')))
  .then(() => {
    // ...
  });const assert = require('node:assert/strict');

assert.doesNotReject(Promise.reject(new TypeError('Wrong value')))
  .then(() => {
    // ...
  });

assert.doesNotThrow(fn[, error][, message])#>

断言函数 fn 不会抛出错误。

【Asserts that the function fn does not throw an error.】

实际上使用 assert.doesNotThrow() 并没有什么用,因为捕获错误然后再抛出并没有任何好处。相反,可以考虑在不应抛出异常的特定代码路径旁边添加注释,并尽量保持错误信息的表达性。

【Using assert.doesNotThrow() is actually not useful because there is no benefit in catching an error and then rethrowing it. Instead, consider adding a comment next to the specific code path that should not throw and keep error messages as expressive as possible.】

当调用 assert.doesNotThrow() 时,它会立即调用 fn 函数。

【When assert.doesNotThrow() is called, it will immediately call the fn function.】

如果抛出一个错误,并且它与 error 参数指定的类型相同,则会抛出 AssertionError。如果错误类型不同,或者 error 参数未定义,则该错误会向调用者传回。

【If an error is thrown and it is the same type as that specified by the error parameter, then an AssertionError is thrown. If the error is of a different type, or if the error parameter is undefined, the error is propagated back to the caller.】

如果指定,error 可以是 ClassRegExp 或验证函数。更多详情请参见 assert.throws()

【If specified, error can be a Class, RegExp, or a validation function. See assert.throws() for more details.】

例如,下面的代码会抛出 TypeError,因为断言中没有匹配的错误类型:

【The following, for instance, will throw the TypeError because there is no matching error type in the assertion:】

import assert from 'node:assert/strict';

assert.doesNotThrow(
  () => {
    throw new TypeError('Wrong value');
  },
  SyntaxError,
);const assert = require('node:assert/strict');

assert.doesNotThrow(
  () => {
    throw new TypeError('Wrong value');
  },
  SyntaxError,
);

但是,以下操作将导致出现带有消息 'Got unwanted exception...' 的 AssertionError

【However, the following will result in an AssertionError with the message 'Got unwanted exception...':】

import assert from 'node:assert/strict';

assert.doesNotThrow(
  () => {
    throw new TypeError('Wrong value');
  },
  TypeError,
);const assert = require('node:assert/strict');

assert.doesNotThrow(
  () => {
    throw new TypeError('Wrong value');
  },
  TypeError,
);

如果抛出 AssertionError 并为 message 参数提供了值,则该 message 的值将附加到 AssertionError 消息中:

【If an AssertionError is thrown and a value is provided for the message parameter, the value of message will be appended to the AssertionError message:】

import assert from 'node:assert/strict';

assert.doesNotThrow(
  () => {
    throw new TypeError('Wrong value');
  },
  /Wrong value/,
  'Whoops',
);
// Throws: AssertionError: Got unwanted exception: Whoopsconst assert = require('node:assert/strict');

assert.doesNotThrow(
  () => {
    throw new TypeError('Wrong value');
  },
  /Wrong value/,
  'Whoops',
);
// Throws: AssertionError: Got unwanted exception: Whoops

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

严格断言模式

assert.strictEqual() 的别名。

【An alias of assert.strictEqual().】

遗留断言模式

稳定性: 3 - 传统:请改用 assert.strictEqual()

测试 actualexpected 参数之间的浅层、强制平等性,使用 == 运算符NaN 会被特殊处理,如果两边都是 NaN,则视为相同。

【Tests shallow, coercive equality between the actual and expected parameters using the == operator. NaN is specially handled and treated as being identical if both sides are NaN.】

import assert from 'node:assert';

assert.equal(1, 1);
// OK, 1 == 1
assert.equal(1, '1');
// OK, 1 == '1'
assert.equal(NaN, NaN);
// OK

assert.equal(1, 2);
// AssertionError: 1 == 2
assert.equal({ a: { b: 1 } }, { a: { b: 1 } });
// AssertionError: { a: { b: 1 } } == { a: { b: 1 } }const assert = require('node:assert');

assert.equal(1, 1);
// OK, 1 == 1
assert.equal(1, '1');
// OK, 1 == '1'
assert.equal(NaN, NaN);
// OK

assert.equal(1, 2);
// AssertionError: 1 == 2
assert.equal({ a: { b: 1 } }, { a: { b: 1 } });
// AssertionError: { a: { b: 1 } } == { a: { b: 1 } }

如果值不相等,将抛出一个 AssertionErrormessage 属性被设置为 message 参数的值。如果 message 参数未定义,则会分配默认的错误消息。如果 message 参数是 Error 的实例,则会抛出该实例,而不是 AssertionError

【If the values are not equal, an AssertionError is thrown with a message property set equal to the value of the message parameter. If the message parameter is undefined, a default error message is assigned. If the message parameter is an instance of an Error then it will be thrown instead of the AssertionError.】

assert.fail([message])#>

使用提供的错误信息或默认错误信息抛出 AssertionError。如果 message 参数是 Error 的实例,则会抛出该实例而不是 AssertionError

【Throws an AssertionError with the provided error message or a default error message. If the message parameter is an instance of an Error then it will be thrown instead of the AssertionError.】

import assert from 'node:assert/strict';

assert.fail();
// AssertionError [ERR_ASSERTION]: Failed

assert.fail('boom');
// AssertionError [ERR_ASSERTION]: boom

assert.fail(new TypeError('need array'));
// TypeError: need arrayconst assert = require('node:assert/strict');

assert.fail();
// AssertionError [ERR_ASSERTION]: Failed

assert.fail('boom');
// AssertionError [ERR_ASSERTION]: boom

assert.fail(new TypeError('need array'));
// TypeError: need array

使用 assert.fail() 时传入两个以上的参数是可行的,但已被弃用。详见下文说明。

【Using assert.fail() with more than two arguments is possible but deprecated. See below for further details.】

assert.fail(actual, expected[, message[, operator[, stackStartFn]]])#>

稳定性: 0 - 已弃用:请改用 assert.fail([message]) 或其他断言函数。

如果 message 为假值,错误信息将被设置为 actualexpected 的值,并由提供的 operator 分隔。如果只提供了 actualexpected 两个参数,operator 将默认为 '!='。如果第三个参数提供了 message,它将被用作错误信息,其余参数将作为属性存储在抛出的对象上。如果提供了 stackStartFn,堆栈中该函数上方的所有堆栈帧将被移除(见 Error.captureStackTrace)。如果没有提供任何参数,将使用默认信息 Failed

【If message is falsy, the error message is set as the values of actual and expected separated by the provided operator. If just the two actual and expected arguments are provided, operator will default to '!='. If message is provided as third argument it will be used as the error message and the other arguments will be stored as properties on the thrown object. If stackStartFn is provided, all stack frames above that function will be removed from stacktrace (see Error.captureStackTrace). If no arguments are given, the default message Failed will be used.】

import assert from 'node:assert/strict';

assert.fail('a', 'b');
// AssertionError [ERR_ASSERTION]: 'a' != 'b'

assert.fail(1, 2, undefined, '>');
// AssertionError [ERR_ASSERTION]: 1 > 2

assert.fail(1, 2, 'fail');
// AssertionError [ERR_ASSERTION]: fail

assert.fail(1, 2, 'whoops', '>');
// AssertionError [ERR_ASSERTION]: whoops

assert.fail(1, 2, new TypeError('need array'));
// TypeError: need arrayconst assert = require('node:assert/strict');

assert.fail('a', 'b');
// AssertionError [ERR_ASSERTION]: 'a' != 'b'

assert.fail(1, 2, undefined, '>');
// AssertionError [ERR_ASSERTION]: 1 > 2

assert.fail(1, 2, 'fail');
// AssertionError [ERR_ASSERTION]: fail

assert.fail(1, 2, 'whoops', '>');
// AssertionError [ERR_ASSERTION]: whoops

assert.fail(1, 2, new TypeError('need array'));
// TypeError: need array

在最后三种情况下,actualexpectedoperator 对错误信息没有影响。

【In the last three cases actual, expected, and operator have no influence on the error message.】

stackStartFn 用于截断异常堆栈跟踪的示例用法:

【Example use of stackStartFn for truncating the exception's stacktrace:】

import assert from 'node:assert/strict';

function suppressFrame() {
  assert.fail('a', 'b', undefined, '!==', suppressFrame);
}
suppressFrame();
// AssertionError [ERR_ASSERTION]: 'a' !== 'b'
//     at repl:1:1
//     at ContextifyScript.Script.runInThisContext (vm.js:44:33)
//     ...const assert = require('node:assert/strict');

function suppressFrame() {
  assert.fail('a', 'b', undefined, '!==', suppressFrame);
}
suppressFrame();
// AssertionError [ERR_ASSERTION]: 'a' !== 'b'
//     at repl:1:1
//     at ContextifyScript.Script.runInThisContext (vm.js:44:33)
//     ...

assert.ifError(value)#>

如果 value 不是 undefinednull,则抛出 value。这在测试回调中的 error 参数时非常有用。堆栈跟踪包含传递给 ifError() 的错误的所有帧,包括 ifError() 本身可能新增的帧。

【Throws value if value is not undefined or null. This is useful when testing the error argument in callbacks. The stack trace contains all frames from the error passed to ifError() including the potential new frames for ifError() itself.】

import assert from 'node:assert/strict';

assert.ifError(null);
// OK
assert.ifError(0);
// AssertionError [ERR_ASSERTION]: ifError got unwanted exception: 0
assert.ifError('error');
// AssertionError [ERR_ASSERTION]: ifError got unwanted exception: 'error'
assert.ifError(new Error());
// AssertionError [ERR_ASSERTION]: ifError got unwanted exception: Error

// Create some random error frames.
let err;
(function errorFrame() {
  err = new Error('test error');
})();

(function ifErrorFrame() {
  assert.ifError(err);
})();
// AssertionError [ERR_ASSERTION]: ifError got unwanted exception: test error
//     at ifErrorFrame
//     at errorFrameconst assert = require('node:assert/strict');

assert.ifError(null);
// OK
assert.ifError(0);
// AssertionError [ERR_ASSERTION]: ifError got unwanted exception: 0
assert.ifError('error');
// AssertionError [ERR_ASSERTION]: ifError got unwanted exception: 'error'
assert.ifError(new Error());
// AssertionError [ERR_ASSERTION]: ifError got unwanted exception: Error

// Create some random error frames.
let err;
(function errorFrame() {
  err = new Error('test error');
})();

(function ifErrorFrame() {
  assert.ifError(err);
})();
// AssertionError [ERR_ASSERTION]: ifError got unwanted exception: test error
//     at ifErrorFrame
//     at errorFrame

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

期望 string 输入匹配正则表达式。

【Expects the string input to match the regular expression.】

import assert from 'node:assert/strict';

assert.match('I will fail', /pass/);
// AssertionError [ERR_ASSERTION]: The input did not match the regular ...

assert.match(123, /pass/);
// AssertionError [ERR_ASSERTION]: The "string" argument must be of type string.

assert.match('I will pass', /pass/);
// OKconst assert = require('node:assert/strict');

assert.match('I will fail', /pass/);
// AssertionError [ERR_ASSERTION]: The input did not match the regular ...

assert.match(123, /pass/);
// AssertionError [ERR_ASSERTION]: The "string" argument must be of type string.

assert.match('I will pass', /pass/);
// OK

如果值不匹配,或者 string 参数的类型不是 string,将抛出一个 AssertionError,其 message 属性设置为 message 参数的值。如果 message 参数未定义,将分配一个默认的错误消息。如果 message 参数是 Error 的实例,则将抛出该实例而不是 AssertionError

【If the values do not match, or if the string argument is of another type than string, an AssertionError is thrown with a message property set equal to the value of the message parameter. If the message parameter is undefined, a default error message is assigned. If the message parameter is an instance of an Error then it will be thrown instead of the AssertionError.】

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

严格断言模式

assert.notDeepStrictEqual() 的别名。

【An alias of assert.notDeepStrictEqual().】

遗留断言模式

测试任何深层不平等。与assert.deepEqual()相反。

【Tests for any deep inequality. Opposite of assert.deepEqual().】

import assert from 'node:assert';

const obj1 = {
  a: {
    b: 1,
  },
};
const obj2 = {
  a: {
    b: 2,
  },
};
const obj3 = {
  a: {
    b: 1,
  },
};
const obj4 = Object.create(obj1);

assert.notDeepEqual(obj1, obj1);
// AssertionError: { a: { b: 1 } } notDeepEqual { a: { b: 1 } }

assert.notDeepEqual(obj1, obj2);
// OK

assert.notDeepEqual(obj1, obj3);
// AssertionError: { a: { b: 1 } } notDeepEqual { a: { b: 1 } }

assert.notDeepEqual(obj1, obj4);
// OKconst assert = require('node:assert');

const obj1 = {
  a: {
    b: 1,
  },
};
const obj2 = {
  a: {
    b: 2,
  },
};
const obj3 = {
  a: {
    b: 1,
  },
};
const obj4 = Object.create(obj1);

assert.notDeepEqual(obj1, obj1);
// AssertionError: { a: { b: 1 } } notDeepEqual { a: { b: 1 } }

assert.notDeepEqual(obj1, obj2);
// OK

assert.notDeepEqual(obj1, obj3);
// AssertionError: { a: { b: 1 } } notDeepEqual { a: { b: 1 } }

assert.notDeepEqual(obj1, obj4);
// OK

如果值是深度相等的,将抛出一个 AssertionError,其 message 属性设置为 message 参数的值。如果 message 参数未定义,将分配一个默认的错误消息。如果 message 参数是 Error 的一个实例,那么将抛出该实例,而不是 AssertionError

【If the values are deeply equal, an AssertionError is thrown with a message property set equal to the value of the message parameter. If the message parameter is undefined, a default error message is assigned. If the message parameter is an instance of an Error then it will be thrown instead of the AssertionError.】

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

用于深严格不等式的测试。与 assert.deepStrictEqual() 相反。

【Tests for deep strict inequality. Opposite of assert.deepStrictEqual().】

import assert from 'node:assert/strict';

assert.notDeepStrictEqual({ a: 1 }, { a: '1' });
// OKconst assert = require('node:assert/strict');

assert.notDeepStrictEqual({ a: 1 }, { a: '1' });
// OK

如果值是深度且严格相等的,将抛出一个 AssertionError,其 message 属性被设置为 message 参数的值。如果 message 参数未定义,则会分配一个默认错误消息。如果 message 参数是 Error 的实例,则会抛出该实例而不是 AssertionError

【If the values are deeply and strictly equal, an AssertionError is thrown with a message property set equal to the value of the message parameter. If the message parameter is undefined, a default error message is assigned. If the message parameter is an instance of an Error then it will be thrown instead of the AssertionError.】

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

严格断言模式

assert.notStrictEqual() 的别名。

【An alias of assert.notStrictEqual().】

遗留断言模式

稳定性: 3 - 传统:请改用 assert.notStrictEqual()

使用 != 运算符 测试浅层、强制性的不平等。NaN 会被特殊处理,如果两边都是 NaN,则被视为相同。

【Tests shallow, coercive inequality with the != operator. NaN is specially handled and treated as being identical if both sides are NaN.】

import assert from 'node:assert';

assert.notEqual(1, 2);
// OK

assert.notEqual(1, 1);
// AssertionError: 1 != 1

assert.notEqual(1, '1');
// AssertionError: 1 != '1'const assert = require('node:assert');

assert.notEqual(1, 2);
// OK

assert.notEqual(1, 1);
// AssertionError: 1 != 1

assert.notEqual(1, '1');
// AssertionError: 1 != '1'

如果数值相等,将抛出一个 AssertionError,并且其 message 属性设置为 message 参数的值。如果 message 参数未定义,则会分配默认的错误消息。如果 message 参数是 Error 的实例,则会抛出该实例,而不是 AssertionError

【If the values are equal, an AssertionError is thrown with a message property set equal to the value of the message parameter. If the message parameter is undefined, a default error message is assigned. If the message parameter is an instance of an Error then it will be thrown instead of the AssertionError.】

assert.notStrictEqual(actual, expected[, message])#>

测试由 Object.is() 确定的 actualexpected 参数之间的严格不等式。

【Tests strict inequality between the actual and expected parameters as determined by Object.is().】

import assert from 'node:assert/strict';

assert.notStrictEqual(1, 2);
// OK

assert.notStrictEqual(1, 1);
// AssertionError [ERR_ASSERTION]: Expected "actual" to be strictly unequal to:
//
// 1

assert.notStrictEqual(1, '1');
// OKconst assert = require('node:assert/strict');

assert.notStrictEqual(1, 2);
// OK

assert.notStrictEqual(1, 1);
// AssertionError [ERR_ASSERTION]: Expected "actual" to be strictly unequal to:
//
// 1

assert.notStrictEqual(1, '1');
// OK

如果值严格相等,则会抛出一个 AssertionError,并且其 message 属性设置为 message 参数的值。如果 message 参数未定义,则会分配一个默认的错误信息。如果 message 参数是 Error 的一个实例,则会抛出它,而不是 AssertionError

【If the values are strictly equal, an AssertionError is thrown with a message property set equal to the value of the message parameter. If the message parameter is undefined, a default error message is assigned. If the message parameter is an instance of an Error then it will be thrown instead of the AssertionError.】

assert.ok(value[, message])#>

测试 value 是否为真值。它等同于 assert.equal(!!value, true, message)

【Tests if value is truthy. It is equivalent to assert.equal(!!value, true, message).】

如果 value 不为真,一个 AssertionError 异常将被抛出,其 message 属性将被设置为 message 参数的值。如果 message 参数为 undefined,则会分配一个默认的错误消息。如果 message 参数是 Error 的实例,则会抛出该实例,而不是 AssertionError。 如果根本没有传入任何参数,message 将被设置为字符串:'未向 `assert.ok()` 传递值参数'

【If value is not truthy, an AssertionError is thrown with a message property set equal to the value of the message parameter. If the message parameter is undefined, a default error message is assigned. If the message parameter is an instance of an Error then it will be thrown instead of the AssertionError. If no arguments are passed in at all message will be set to the string: 'No value argument passed to `assert.ok()`'.】

请注意,在 repl 中错误信息与在文件中抛出的错误信息会不同!详细信息见下文。

【Be aware that in the repl the error message will be different to the one thrown in a file! See below for further details.】

import assert from 'node:assert/strict';

assert.ok(true);
// OK
assert.ok(1);
// OK

assert.ok();
// AssertionError: No value argument passed to `assert.ok()`

assert.ok(false, 'it\'s false');
// AssertionError: it's false

// In the repl:
assert.ok(typeof 123 === 'string');
// AssertionError: false == true

// In a file (e.g. test.js):
assert.ok(typeof 123 === 'string');
// AssertionError: The expression evaluated to a falsy value:
//
//   assert.ok(typeof 123 === 'string')

assert.ok(false);
// AssertionError: The expression evaluated to a falsy value:
//
//   assert.ok(false)

assert.ok(0);
// AssertionError: The expression evaluated to a falsy value:
//
//   assert.ok(0)const assert = require('node:assert/strict');

assert.ok(true);
// OK
assert.ok(1);
// OK

assert.ok();
// AssertionError: No value argument passed to `assert.ok()`

assert.ok(false, 'it\'s false');
// AssertionError: it's false

// In the repl:
assert.ok(typeof 123 === 'string');
// AssertionError: false == true

// In a file (e.g. test.js):
assert.ok(typeof 123 === 'string');
// AssertionError: The expression evaluated to a falsy value:
//
//   assert.ok(typeof 123 === 'string')

assert.ok(false);
// AssertionError: The expression evaluated to a falsy value:
//
//   assert.ok(false)

assert.ok(0);
// AssertionError: The expression evaluated to a falsy value:
//
//   assert.ok(0)
import assert from 'node:assert/strict';

// Using `assert()` works the same:
assert(0);
// AssertionError: The expression evaluated to a falsy value:
//
//   assert(0)const assert = require('node:assert');

// Using `assert()` works the same:
assert(0);
// AssertionError: The expression evaluated to a falsy value:
//
//   assert(0)

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

等待 asyncFn 的 promise,或者如果 asyncFn 是一个函数,则立即调用该函数并等待返回的 promise 完成。然后它将检查该 promise 是否被拒绝。

【Awaits the asyncFn promise or, if asyncFn is a function, immediately calls the function and awaits the returned promise to complete. It will then check that the promise is rejected.】

如果 asyncFn 是一个函数并且它同步抛出一个错误,assert.rejects() 将返回一个带有该错误的被拒绝的 Promise。如果该函数没有返回 promise,assert.rejects() 将返回一个带有 ERR_INVALID_RETURN_VALUE 错误的被拒绝的 Promise。在这两种情况下,错误处理程序都会被跳过。

【If asyncFn is a function and it throws an error synchronously, assert.rejects() will return a rejected Promise with that error. If the function does not return a promise, assert.rejects() will return a rejected Promise with an ERR_INVALID_RETURN_VALUE error. In both cases the error handler is skipped.】

除了异步性质需要等待完成外,其行为与 assert.throws() 完全相同。

【Besides the async nature to await the completion behaves identically to assert.throws().】

如果指定,error 可以是 ClassRegExp、一个验证函数、一个对象(其中每个属性都会被测试),或者一个错误实例(其中每个属性都会被测试,包括不可枚举的 messagename 属性)。

【If specified, error can be a Class, RegExp, a validation function, an object where each property will be tested for, or an instance of error where each property will be tested for including the non-enumerable message and name properties.】

如果指定,当 asyncFn 未能拒绝时,message 将是 AssertionError 提供的消息。

【If specified, message will be the message provided by the AssertionError if the asyncFn fails to reject.】

import assert from 'node:assert/strict';

await assert.rejects(
  async () => {
    throw new TypeError('Wrong value');
  },
  {
    name: 'TypeError',
    message: 'Wrong value',
  },
);const assert = require('node:assert/strict');

(async () => {
  await assert.rejects(
    async () => {
      throw new TypeError('Wrong value');
    },
    {
      name: 'TypeError',
      message: 'Wrong value',
    },
  );
})();
import assert from 'node:assert/strict';

await assert.rejects(
  async () => {
    throw new TypeError('Wrong value');
  },
  (err) => {
    assert.strictEqual(err.name, 'TypeError');
    assert.strictEqual(err.message, 'Wrong value');
    return true;
  },
);const assert = require('node:assert/strict');

(async () => {
  await assert.rejects(
    async () => {
      throw new TypeError('Wrong value');
    },
    (err) => {
      assert.strictEqual(err.name, 'TypeError');
      assert.strictEqual(err.message, 'Wrong value');
      return true;
    },
  );
})();
import assert from 'node:assert/strict';

assert.rejects(
  Promise.reject(new Error('Wrong value')),
  Error,
).then(() => {
  // ...
});const assert = require('node:assert/strict');

assert.rejects(
  Promise.reject(new Error('Wrong value')),
  Error,
).then(() => {
  // ...
});

error 不能是字符串。如果将字符串作为第二个参数提供,则假定已省略 error,该字符串将用于 message。这可能导致容易被忽视的错误。如果第二个参数使用字符串,请仔细阅读 assert.throws() 中的示例。

assert.strictEqual(actual, expected[, message])#>

根据 Object.is() 判断,测试 actualexpected 参数是否严格相等。

【Tests strict equality between the actual and expected parameters as determined by Object.is().】

import assert from 'node:assert/strict';

assert.strictEqual(1, 2);
// AssertionError [ERR_ASSERTION]: Expected inputs to be strictly equal:
//
// 1 !== 2

assert.strictEqual(1, 1);
// OK

assert.strictEqual('Hello foobar', 'Hello World!');
// AssertionError [ERR_ASSERTION]: Expected inputs to be strictly equal:
// + actual - expected
//
// + 'Hello foobar'
// - 'Hello World!'
//          ^

const apples = 1;
const oranges = 2;
assert.strictEqual(apples, oranges, `apples ${apples} !== oranges ${oranges}`);
// AssertionError [ERR_ASSERTION]: apples 1 !== oranges 2

assert.strictEqual(1, '1', new TypeError('Inputs are not identical'));
// TypeError: Inputs are not identicalconst assert = require('node:assert/strict');

assert.strictEqual(1, 2);
// AssertionError [ERR_ASSERTION]: Expected inputs to be strictly equal:
//
// 1 !== 2

assert.strictEqual(1, 1);
// OK

assert.strictEqual('Hello foobar', 'Hello World!');
// AssertionError [ERR_ASSERTION]: Expected inputs to be strictly equal:
// + actual - expected
//
// + 'Hello foobar'
// - 'Hello World!'
//          ^

const apples = 1;
const oranges = 2;
assert.strictEqual(apples, oranges, `apples ${apples} !== oranges ${oranges}`);
// AssertionError [ERR_ASSERTION]: apples 1 !== oranges 2

assert.strictEqual(1, '1', new TypeError('Inputs are not identical'));
// TypeError: Inputs are not identical

如果这些值不完全相等,将抛出一个 AssertionError,并且其 message 属性设置为 message 参数的值。如果 message 参数未定义,将分配一个默认的错误消息。如果 message 参数是 Error 的一个实例,那么将抛出该实例,而不是 AssertionError

【If the values are not strictly equal, an AssertionError is thrown with a message property set equal to the value of the message parameter. If the message parameter is undefined, a default error message is assigned. If the message parameter is an instance of an Error then it will be thrown instead of the AssertionError.】

assert.throws(fn[, error][, message])#>

期望函数 fn 抛出一个错误。

【Expects the function fn to throw an error.】

如果指定,error 可以是 ClassRegExp、一个验证函数、一个验证对象(其中每个属性都将进行严格的深度相等测试),或者一个错误实例(其中每个属性,包括不可枚举的 messagename 属性,都将进行严格的深度相等测试)。使用对象时,还可以在验证字符串属性时使用正则表达式。示例见下文。

【If specified, error can be a Class, RegExp, a validation function, a validation object where each property will be tested for strict deep equality, or an instance of error where each property will be tested for strict deep equality including the non-enumerable message and name properties. When using an object, it is also possible to use a regular expression, when validating against a string property. See below for examples.】

如果指定,message 将会被附加到 AssertionError 提供的消息中,当 fn 调用未抛出异常或在错误验证失败时。

【If specified, message will be appended to the message provided by the AssertionError if the fn call fails to throw or in case the error validation fails.】

自定义验证对象/错误实例:

【Custom validation object/error instance:】

import assert from 'node:assert/strict';

const err = new TypeError('Wrong value');
err.code = 404;
err.foo = 'bar';
err.info = {
  nested: true,
  baz: 'text',
};
err.reg = /abc/i;

assert.throws(
  () => {
    throw err;
  },
  {
    name: 'TypeError',
    message: 'Wrong value',
    info: {
      nested: true,
      baz: 'text',
    },
    // Only properties on the validation object will be tested for.
    // Using nested objects requires all properties to be present. Otherwise
    // the validation is going to fail.
  },
);

// Using regular expressions to validate error properties:
assert.throws(
  () => {
    throw err;
  },
  {
    // The `name` and `message` properties are strings and using regular
    // expressions on those will match against the string. If they fail, an
    // error is thrown.
    name: /^TypeError$/,
    message: /Wrong/,
    foo: 'bar',
    info: {
      nested: true,
      // It is not possible to use regular expressions for nested properties!
      baz: 'text',
    },
    // The `reg` property contains a regular expression and only if the
    // validation object contains an identical regular expression, it is going
    // to pass.
    reg: /abc/i,
  },
);

// Fails due to the different `message` and `name` properties:
assert.throws(
  () => {
    const otherErr = new Error('Not found');
    // Copy all enumerable properties from `err` to `otherErr`.
    for (const [key, value] of Object.entries(err)) {
      otherErr[key] = value;
    }
    throw otherErr;
  },
  // The error's `message` and `name` properties will also be checked when using
  // an error as validation object.
  err,
);const assert = require('node:assert/strict');

const err = new TypeError('Wrong value');
err.code = 404;
err.foo = 'bar';
err.info = {
  nested: true,
  baz: 'text',
};
err.reg = /abc/i;

assert.throws(
  () => {
    throw err;
  },
  {
    name: 'TypeError',
    message: 'Wrong value',
    info: {
      nested: true,
      baz: 'text',
    },
    // Only properties on the validation object will be tested for.
    // Using nested objects requires all properties to be present. Otherwise
    // the validation is going to fail.
  },
);

// Using regular expressions to validate error properties:
assert.throws(
  () => {
    throw err;
  },
  {
    // The `name` and `message` properties are strings and using regular
    // expressions on those will match against the string. If they fail, an
    // error is thrown.
    name: /^TypeError$/,
    message: /Wrong/,
    foo: 'bar',
    info: {
      nested: true,
      // It is not possible to use regular expressions for nested properties!
      baz: 'text',
    },
    // The `reg` property contains a regular expression and only if the
    // validation object contains an identical regular expression, it is going
    // to pass.
    reg: /abc/i,
  },
);

// Fails due to the different `message` and `name` properties:
assert.throws(
  () => {
    const otherErr = new Error('Not found');
    // Copy all enumerable properties from `err` to `otherErr`.
    for (const [key, value] of Object.entries(err)) {
      otherErr[key] = value;
    }
    throw otherErr;
  },
  // The error's `message` and `name` properties will also be checked when using
  // an error as validation object.
  err,
);

使用构造函数验证 instanceof:

【Validate instanceof using constructor:】

import assert from 'node:assert/strict';

assert.throws(
  () => {
    throw new Error('Wrong value');
  },
  Error,
);const assert = require('node:assert/strict');

assert.throws(
  () => {
    throw new Error('Wrong value');
  },
  Error,
);

使用 RegExp 验证错误信息:

【Validate error message using RegExp:】

使用正则表达式会对错误对象运行 .toString,因此也会包含错误名称。

【Using a regular expression runs .toString on the error object, and will therefore also include the error name.】

import assert from 'node:assert/strict';

assert.throws(
  () => {
    throw new Error('Wrong value');
  },
  /^Error: Wrong value$/,
);const assert = require('node:assert/strict');

assert.throws(
  () => {
    throw new Error('Wrong value');
  },
  /^Error: Wrong value$/,
);

自定义错误验证:

【Custom error validation:】

该函数必须返回 true 以表示所有内部验证通过。否则将以 AssertionError 失败。

【The function must return true to indicate all internal validations passed. It will otherwise fail with an AssertionError.】

import assert from 'node:assert/strict';

assert.throws(
  () => {
    throw new Error('Wrong value');
  },
  (err) => {
    assert(err instanceof Error);
    assert(/value/.test(err));
    // Avoid returning anything from validation functions besides `true`.
    // Otherwise, it's not clear what part of the validation failed. Instead,
    // throw an error about the specific validation that failed (as done in this
    // example) and add as much helpful debugging information to that error as
    // possible.
    return true;
  },
  'unexpected error',
);const assert = require('node:assert/strict');

assert.throws(
  () => {
    throw new Error('Wrong value');
  },
  (err) => {
    assert(err instanceof Error);
    assert(/value/.test(err));
    // Avoid returning anything from validation functions besides `true`.
    // Otherwise, it's not clear what part of the validation failed. Instead,
    // throw an error about the specific validation that failed (as done in this
    // example) and add as much helpful debugging information to that error as
    // possible.
    return true;
  },
  'unexpected error',
);

error 不能是字符串。如果第二个参数提供的是字符串,则假定省略了 error,该字符串将用于 message。这可能会导致容易被忽略的错误。使用与抛出的错误消息相同的消息将导致 ERR_AMBIGUOUS_ARGUMENT 错误。如果将字符串作为第二个参数,请仔细阅读下面的示例:

import assert from 'node:assert/strict';

function throwingFirst() {
  throw new Error('First');
}

function throwingSecond() {
  throw new Error('Second');
}

function notThrowing() {}

// The second argument is a string and the input function threw an Error.
// The first case will not throw as it does not match for the error message
// thrown by the input function!
assert.throws(throwingFirst, 'Second');
// In the next example the message has no benefit over the message from the
// error and since it is not clear if the user intended to actually match
// against the error message, Node.js throws an `ERR_AMBIGUOUS_ARGUMENT` error.
assert.throws(throwingSecond, 'Second');
// TypeError [ERR_AMBIGUOUS_ARGUMENT]

// The string is only used (as message) in case the function does not throw:
assert.throws(notThrowing, 'Second');
// AssertionError [ERR_ASSERTION]: Missing expected exception: Second

// If it was intended to match for the error message do this instead:
// It does not throw because the error messages match.
assert.throws(throwingSecond, /Second$/);

// If the error message does not match, an AssertionError is thrown.
assert.throws(throwingFirst, /Second$/);
// AssertionError [ERR_ASSERTION]const assert = require('node:assert/strict');

function throwingFirst() {
  throw new Error('First');
}

function throwingSecond() {
  throw new Error('Second');
}

function notThrowing() {}

// The second argument is a string and the input function threw an Error.
// The first case will not throw as it does not match for the error message
// thrown by the input function!
assert.throws(throwingFirst, 'Second');
// In the next example the message has no benefit over the message from the
// error and since it is not clear if the user intended to actually match
// against the error message, Node.js throws an `ERR_AMBIGUOUS_ARGUMENT` error.
assert.throws(throwingSecond, 'Second');
// TypeError [ERR_AMBIGUOUS_ARGUMENT]

// The string is only used (as message) in case the function does not throw:
assert.throws(notThrowing, 'Second');
// AssertionError [ERR_ASSERTION]: Missing expected exception: Second

// If it was intended to match for the error message do this instead:
// It does not throw because the error messages match.
assert.throws(throwingSecond, /Second$/);

// If the error message does not match, an AssertionError is thrown.
assert.throws(throwingFirst, /Second$/);
// AssertionError [ERR_ASSERTION]

由于符号容易混淆且容易出错,请避免将字符串作为第二个参数。

【Due to the confusing error-prone notation, avoid a string as the second argument.】

Node.js 中文网 - 粤ICP备13048890号