Skip to content

断言

[稳定: 2 - 稳定]

稳定: 2 稳定性: 2 - 稳定

源代码: lib/assert.js

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

严格断言模式

[历史]

版本变更
v15.0.0作为 require('node:assert/strict') 公开。
v13.9.0, v12.16.2将“严格模式”更改为“严格断言模式”,将“遗留模式”更改为“遗留断言模式”,以避免与更常用的“严格模式”含义混淆。
v9.9.0向严格断言模式添加了错误差异。
v9.9.0向 assert 模块添加了严格断言模式。
v9.9.0添加于: v9.9.0

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

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

要使用严格断言模式:

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

示例错误差异:

js
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
//   ]
js
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() 文档。

传统断言模式

传统断言模式在以下方法中使用== 运算符:

要使用传统断言模式:

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

传统断言模式可能会产生令人意外的结果,尤其是在使用assert.deepEqual()时:

js
// WARNING: 在传统断言模式下,这不会抛出 AssertionError!
assert.deepEqual(/a/gi, new Date())

类:assert.AssertionError

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

new assert.AssertionError(options)

新增于:v0.1.21

  • options <对象>
    • message <字符串> 如果提供,则错误消息将设置为该值。
    • actual <任意> 错误实例上的 actual 属性。
    • expected <任意> 错误实例上的 expected 属性。
    • operator <字符串> 错误实例上的 operator 属性。
    • stackStartFn <函数> 如果提供,则生成的堆栈跟踪将忽略此函数之前的帧。

Error 的子类,指示断言失败。

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

js
import assert from 'node:assert'

// 生成一个 AssertionError 以便稍后比较错误消息:
const { message } = new assert.AssertionError({
  actual: 1,
  expected: 2,
  operator: 'strictEqual',
})

// 验证错误输出:
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)
}
js
const assert = require('node:assert')

// 生成一个 AssertionError 以便稍后比较错误消息:
const { message } = new assert.AssertionError({
  actual: 1,
  expected: 2,
  operator: 'strictEqual',
})

// 验证错误输出:
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

[历史]

版本变更
v20.1.0assert.CallTracker 类已弃用,将在未来版本中移除。
v14.2.0, v12.19.0新增于: v14.2.0, v12.19.0

[稳定性: 0 - 已弃用]

稳定性: 0 稳定性: 0 - 已弃用

此功能已弃用,将在未来版本中移除。请考虑使用替代方案,例如 mock 辅助函数。

new assert.CallTracker()

新增于: v14.2.0, v12.19.0

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

js
import assert from 'node:assert'
import process from 'node:process'

const tracker = new assert.CallTracker()

function func() {}

// callsfunc() 必须在 tracker.verify() 之前被精确调用 1 次。
const callsfunc = tracker.calls(func, 1)

callsfunc()

// 调用 tracker.verify() 并验证所有 tracker.calls() 函数是否被精确调用了指定的次数。
process.on('exit', () => {
  tracker.verify()
})
js
const assert = require('node:assert')
const process = require('node:process')

const tracker = new assert.CallTracker()

function func() {}

// callsfunc() 必须在 tracker.verify() 之前被精确调用 1 次。
const callsfunc = tracker.calls(func, 1)

callsfunc()

// 调用 tracker.verify() 并验证所有 tracker.calls() 函数是否被精确调用了指定的次数。
process.on('exit', () => {
  tracker.verify()
})

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

新增于: v14.2.0, v12.19.0

该包装函数预期被精确调用 exact 次。如果在调用 tracker.verify() 时,该函数没有被精确调用 exact 次,则 tracker.verify() 将抛出错误。

js
import assert from 'node:assert'

// 创建调用跟踪器。
const tracker = new assert.CallTracker()

function func() {}

// 返回一个包装 func() 的函数,该函数必须在 tracker.verify() 之前被精确调用指定次数。
const callsfunc = tracker.calls(func)
js
const assert = require('node:assert')

// 创建调用跟踪器。
const tracker = new assert.CallTracker()

function func() {}

// 返回一个包装 func() 的函数,该函数必须在 tracker.verify() 之前被精确调用指定次数。
const callsfunc = tracker.calls(func)

tracker.getCalls(fn)

新增于:v18.8.0, v16.18.0

js
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] }])
js
const assert = require('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] }])

tracker.report()

新增于: v14.2.0, v12.19.0

数组包含有关预期调用次数和实际调用次数不相符的函数的信息。

js
import assert from 'node:assert'

// 创建调用跟踪器。
const tracker = new assert.CallTracker()

function func() {}

// 返回一个包装 func() 的函数,该函数必须在 tracker.verify() 之前被精确调用指定次数。
const callsfunc = tracker.calls(func, 2)

// 返回一个包含 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
//  }
// ]
js
const assert = require('node:assert')

// 创建调用跟踪器。
const tracker = new assert.CallTracker()

function func() {}

// 返回一个包装 func() 的函数,该函数必须在 tracker.verify() 之前被精确调用指定次数。
const callsfunc = tracker.calls(func, 2)

// 返回一个包含 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])

新增于:v18.8.0, v16.18.0

重置调用跟踪器的调用。如果将已跟踪函数作为参数传递,则将重置其调用。如果未传递任何参数,则将重置所有已跟踪函数。

js
import assert from 'node:assert'

const tracker = new assert.CallTracker()

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

callsfunc()
// Tracker 被调用了一次
assert.strictEqual(tracker.getCalls(callsfunc).length, 1)

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

const tracker = new assert.CallTracker()

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

callsfunc()
// Tracker 被调用了一次
assert.strictEqual(tracker.getCalls(callsfunc).length, 1)

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

tracker.verify()

新增于:v14.2.0, v12.19.0

迭代传递给 tracker.calls() 的函数列表,对于未被调用预期次数的函数将抛出错误。

js
import assert from 'node:assert'

// 创建调用跟踪器。
const tracker = new assert.CallTracker()

function func() {}

// 返回一个包装 func() 的函数,该函数必须在 tracker.verify() 之前被精确调用指定次数。
const callsfunc = tracker.calls(func, 2)

callsfunc()

// 将抛出错误,因为 callsfunc() 只被调用了一次。
tracker.verify()
js
const assert = require('node:assert')

// 创建调用跟踪器。
const tracker = new assert.CallTracker()

function func() {}

// 返回一个包装 func() 的函数,该函数必须在 tracker.verify() 之前被精确调用指定次数。
const callsfunc = tracker.calls(func, 2)

callsfunc()

// 将抛出错误,因为 callsfunc() 只被调用了一次。
tracker.verify()

assert(value[, message])

新增于:v0.5.9

assert.ok() 的别名。

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

[历史]

版本变更
v22.2.0, v20.15.0现在也比较 Error 原因和 errors 属性。
v18.0.0现在也比较正则表达式的 lastIndex 属性。
v16.0.0, v14.18.0在传统断言模式下,状态从已弃用更改为传统。
v14.0.0如果两边都是 NaN,则现在将 NaN 视为相同。
v12.0.0现在正确比较类型标签,并且进行了一些小的比较调整,以使检查结果不那么令人意外。
v9.0.0现在正确比较 Error 名称和消息。
v8.0.0还比较 SetMap 内容。
v6.4.0, v4.7.1现在正确处理类型化数组切片。
v6.1.0, v4.5.0现在可以使用具有循环引用的对象作为输入。
v5.10.1, v4.4.3正确处理非 Uint8Array 类型化数组。
v0.1.21新增于:v0.1.21

严格断言模式

assert.deepStrictEqual() 的别名。

传统断言模式

[稳定:3 - 传统]

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

测试 actualexpected 参数之间的深度相等性。建议改用 assert.deepStrictEqual()assert.deepEqual() 可能会有令人意外的结果。

深度相等 意味着子对象的枚举“自身”属性也通过以下规则递归评估。

深度比较细节

  • 原生值使用== 运算符进行比较,NaN 除外。如果两侧都是 NaN,则将其视为相同。
  • 对象的类型标签应该相同。
  • 只考虑可枚举的“自身”属性
  • Error 的名称、消息、原因和错误始终进行比较,即使这些不是可枚举属性。
  • 对象包装器 既作为对象又作为解包值进行比较。
  • Object 属性的比较顺序无关紧要。
  • Map 的键和Set 的项的比较顺序无关紧要。
  • 当双方不同或双方都遇到循环引用时,递归停止。
  • 实现不测试对象的[[Prototype]]
  • 不比较Symbol 属性。
  • WeakMapWeakSet 的比较不依赖于它们的值,只依赖于它们的实例。
  • RegExp 的 lastIndex、flags 和 source 始终进行比较,即使这些不是可枚举属性。

下面的例子不会抛出AssertionError,因为原生值使用== 运算符进行比较。

js
import assert from 'node:assert'
// WARNING: 这不会抛出 AssertionError!

assert.deepEqual('+00000000', false)
js
const assert = require('node:assert')
// WARNING: 这不会抛出 AssertionError!

assert.deepEqual('+00000000', false)

“深度”相等意味着子对象的的可枚举“自身”属性也会被评估:

js
import assert from 'node:assert'

const obj1 = {
  a: {
    b: 1,
  },
}
const obj2 = {
  a: {
    b: 2,
  },
}
const obj3 = {
  a: {
    b: 1,
  },
}
const obj4 = { __proto__: obj1 }

assert.deepEqual(obj1, obj1)
// OK

// b 的值不同:
assert.deepEqual(obj1, obj2)
// AssertionError: { a: { b: 1 } } deepEqual { a: { b: 2 } }

assert.deepEqual(obj1, obj3)
// OK

// 原型会被忽略:
assert.deepEqual(obj1, obj4)
// AssertionError: { a: { b: 1 } } deepEqual {}
js
const assert = require('node:assert')

const obj1 = {
  a: {
    b: 1,
  },
}
const obj2 = {
  a: {
    b: 2,
  },
}
const obj3 = {
  a: {
    b: 1,
  },
}
const obj4 = { __proto__: obj1 }

assert.deepEqual(obj1, obj1)
// OK

// b 的值不同:
assert.deepEqual(obj1, obj2)
// AssertionError: { a: { b: 1 } } deepEqual { a: { b: 2 } }

assert.deepEqual(obj1, obj3)
// OK

// 原型会被忽略:
assert.deepEqual(obj1, obj4)
// AssertionError: { a: { b: 1 } } deepEqual {}

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

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

[历史]

版本变更
v22.2.0, v20.15.0现在也比较 Error 的 cause 和 errors 属性。
v18.0.0现在也比较正则表达式的 lastIndex 属性。
v9.0.0现在比较可枚举的 Symbol 属性。
v9.0.0现在使用 SameValueZero 比较来比较 NaN
v8.5.0现在正确比较 Error 的名称和消息。
v8.0.0也比较 SetMap 的内容。
v6.1.0现在可以使用具有循环引用的对象作为输入。
v6.4.0, v4.7.1现在正确处理 Typed Array 切片。
v5.10.1, v4.4.3正确处理非 Uint8Array Typed Array。
v1.2.0在 v1.2.0 中添加

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

比较细节

  • 使用 Object.is() 比较原始值。
  • 对象的 类型标签 应该相同。
  • 使用 === 运算符 比较对象的 [[Prototype]]
  • 只考虑 可枚举的“自身”属性
  • 始终比较 Error 的名称、消息、原因和错误,即使这些不是可枚举属性。也比较 errors
  • 也比较可枚举的自身 Symbol 属性。
  • 同时将 对象包装器 作为对象和解包后的值进行比较。
  • 对象属性的比较顺序无关紧要。
  • Map 的键和 Set 的项的比较顺序无关紧要。
  • 当双方不同或双方遇到循环引用时,递归停止。
  • WeakMapWeakSet 的比较不依赖于它们的值。详情见下文。
  • 始终比较 RegExp 的 lastIndex、flags 和 source,即使这些不是可枚举属性。
js
import assert from 'node:assert/strict'

// 因为 1 !== '1',所以这个测试失败。
assert.deepStrictEqual({ a: 1 }, { a: '1' })
// AssertionError: Expected inputs to be strictly deep-equal:
// + actual - expected
//
//   {
// +   a: 1
// -   a: '1'
//   }

// 以下对象没有自身属性
const date = new Date()
const object = {}
const fakeDate = {}
Object.setPrototypeOf(fakeDate, Date.prototype)

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

// 不同的类型标签:
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)
// 因为 Object.is(NaN, NaN) 为 true,所以这个测试通过。

// 不同的解包数字:
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'))
// 通过,因为对象和字符串在解包后是相同的。

assert.deepStrictEqual(-0, -0)
// 通过

// 不同的零:
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 })
// 通过,因为两个对象上是相同的 Symbol。

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)
// 通过,因为无法比较条目

// 失败,因为 weakMap3 有一个 weakMap1 不包含的属性:
assert.deepStrictEqual(weakMap1, weakMap3)
// AssertionError: Expected inputs to be strictly deep-equal:
// + actual - expected
//
//   WeakMap {
// +   [items unknown]
// -   [items unknown],
// -   unequal: true
//   }
js
const assert = require('node:assert/strict')

// 因为 1 !== '1',所以这个测试失败。
assert.deepStrictEqual({ a: 1 }, { a: '1' })
// AssertionError: Expected inputs to be strictly deep-equal:
// + actual - expected
//
//   {
// +   a: 1
// -   a: '1'
//   }

// 以下对象没有自身属性
const date = new Date()
const object = {}
const fakeDate = {}
Object.setPrototypeOf(fakeDate, Date.prototype)

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

// 不同的类型标签:
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)
// 因为 Object.is(NaN, NaN) 为 true,所以这个测试通过。

// 不同的解包数字:
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'))
// 通过,因为对象和字符串在解包后是相同的。

assert.deepStrictEqual(-0, -0)
// 通过

// 不同的零:
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 })
// 通过,因为两个对象上是相同的 Symbol。

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)
// 通过,因为无法比较条目

// 失败,因为 weakMap3 有一个 weakMap1 不包含的属性:
assert.deepStrictEqual(weakMap1, weakMap3)
// AssertionError: Expected inputs to be strictly deep-equal:
// + actual - expected
//
//   WeakMap {
// +   [items unknown]
// -   [items unknown],
// -   unequal: true
//   }

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

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

[历史]

版本变更
v16.0.0此 API 不再是实验性的。
v13.6.0, v12.16.0添加于:v13.6.0, v12.16.0

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

js
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/)
// OK
js
const 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

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

新增于: v10.0.0

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

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

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

如果指定,error 可以是 ClassRegExp 或一个验证函数。参见 assert.throws() 获取更多细节。

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

js
import assert from 'node:assert/strict'

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

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

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

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

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

[历史]

版本变更
v5.11.0, v4.4.5message 参数现在已生效。
v4.2.0error 参数现在可以是箭头函数。
v0.1.21新增于:v0.1.21

断言函数 fn 不抛出错误。

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

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

如果抛出错误,并且其类型与 error 参数指定的类型相同,则会抛出 AssertionError。如果错误的类型不同,或者 error 参数未定义,则错误将传播回调用方。

如果指定,error 可以是 正则表达式 或验证函数。有关更多详细信息,请参阅 assert.throws()

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

js
import assert from 'node:assert/strict'

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

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

但是,以下代码将导致出现带有消息“Got unwanted exception...”的 AssertionError

js
import assert from 'node:assert/strict'

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

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

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

js
import assert from 'node:assert/strict'

assert.doesNotThrow(
  () => {
    throw new TypeError('Wrong value')
  },
  /Wrong value/,
  'Whoops'
)
// 抛出:AssertionError: Got unwanted exception: Whoops
js
const assert = require('node:assert/strict')

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

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

[历史]

版本变更
v16.0.0, v14.18.0在 Legacy 断言模式下,状态从已弃用更改为 Legacy。
v14.0.0如果两侧都是 NaN,则现在将 NaN 视为相同。
v0.1.21添加于:v0.1.21

严格断言模式

assert.strictEqual() 的别名。

Legacy 断言模式

[稳定:3 - Legacy]

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

使用 == 运算符 测试 actualexpected 参数之间的浅层、强制类型转换相等性。NaN 具有特殊处理,如果两侧都是 NaN,则视为相同。

js
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 } }
js
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 } }

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

assert.fail([message])

新增于: v0.1.21

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

js
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 array
js
const 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() 是可能的,但已弃用。详情请见下文。

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

[历史]

版本变更
v10.0.0调用 assert.fail() 使用多个参数已弃用,并发出警告。
v0.1.21新增于:v0.1.21

[稳定性: 0 - 已弃用]

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

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

js
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 array
js
const 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 对错误消息没有影响。

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

js
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)
//     ...
js
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)

[历史]

版本变更
v10.0.0不再抛出原始错误,而是将其包装到一个包含完整堆栈跟踪的 [AssertionError][] 中。
v10.0.0value 现在只能是 undefinednull。在此之前,所有假值都与 null 一样处理,不会抛出异常。
v0.1.97v0.1.97 版本新增

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

js
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

// 创建一些随机的错误帧。
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
js
const 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

// 创建一些随机的错误帧。
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])

[历史]

版本变更
v16.0.0此 API 不再是实验性的。
v13.6.0, v12.16.0添加于:v13.6.0, v12.16.0

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

js
import assert from 'node:assert/strict'

assert.match('I will fail', /pass/)
// AssertionError [ERR_ASSERTION]: 输入与正则表达式不匹配...

assert.match(123, /pass/)
// AssertionError [ERR_ASSERTION]: "string" 参数必须为字符串类型。

assert.match('I will pass', /pass/)
// OK
js
const assert = require('node:assert/strict')

assert.match('I will fail', /pass/)
// AssertionError [ERR_ASSERTION]: 输入与正则表达式不匹配...

assert.match(123, /pass/)
// AssertionError [ERR_ASSERTION]: "string" 参数必须为字符串类型。

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

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

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

[历史]

版本变更
v16.0.0, v14.18.0在 Legacy 断言模式下,状态从已弃用更改为 Legacy。
v14.0.0如果两侧都是 NaN,则现在将 NaN 视为相同。
v9.0.0现在正确比较 Error 名称和消息。
v8.0.0也比较 SetMap 内容。
v6.4.0, v4.7.1现在正确处理类型化数组切片。
v6.1.0, v4.5.0现在可以使用具有循环引用的对象作为输入。
v5.10.1, v4.4.3正确处理非 Uint8Array 类型化数组。
v0.1.21新增于:v0.1.21

严格断言模式

assert.notDeepStrictEqual() 的别名。

传统断言模式

[稳定:3 - 传统]

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

测试任何深度不相等。assert.deepEqual() 的反义词。

js
import assert from 'node:assert'

const obj1 = {
  a: {
    b: 1,
  },
}
const obj2 = {
  a: {
    b: 2,
  },
}
const obj3 = {
  a: {
    b: 1,
  },
}
const obj4 = { __proto__: 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
js
const assert = require('node:assert')

const obj1 = {
  a: {
    b: 1,
  },
}
const obj2 = {
  a: {
    b: 2,
  },
}
const obj3 = {
  a: {
    b: 1,
  },
}
const obj4 = { __proto__: 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

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

[历史]

版本变更
v9.0.0-0+0 不再被认为相等。
v9.0.0NaN 现在使用 SameValueZero 进行比较。
v9.0.0Error 的名称和消息现在被正确比较。
v8.0.0SetMap 的内容也被比较。
v6.1.0现在可以使用包含循环引用的对象作为输入。
v6.4.0, v4.7.1现在正确处理类型化数组切片。
v5.10.1, v4.4.3正确处理非 Uint8Array 类型化数组。
v1.2.0添加于:v1.2.0

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

js
import assert from 'node:assert/strict'

assert.notDeepStrictEqual({ a: 1 }, { a: '1' })
// OK
js
const assert = require('node:assert/strict')

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

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

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

[历史]

版本变更
v16.0.0, v14.18.0在传统断言模式下,状态从已弃用更改为传统。
v14.0.0如果双方都是 NaN,则现在将 NaN 视为相同。
v0.1.21添加于:v0.1.21

严格断言模式

assert.notStrictEqual() 的别名。

传统断言模式

[稳定:3 - 传统]

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

使用 != 运算符 测试浅层、强制不等式。NaN 将被特殊处理,如果双方都是 NaN,则视为相同。

js
import assert from 'node:assert'

assert.notEqual(1, 2)
// OK

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

assert.notEqual(1, '1')
// AssertionError: 1 != '1'
js
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

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

[历史]

版本变更
v10.0.0使用的比较方式从严格相等更改为 Object.is()
v0.1.21v0.1.21 版本中添加

根据 Object.is() 确定 actualexpected 参数之间的严格不等性。

js
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')
// OK
js
const 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

assert.ok(value[, message])

[历史]

版本变更
v10.0.0assert.ok()(无参数)现在将使用预定义的错误消息。
v0.1.21新增于:v0.1.21

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

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

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

js
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

// 在 repl 中:
assert.ok(typeof 123 === 'string')
// AssertionError: false == true

// 在文件中(例如 test.js):
assert.ok(typeof 123 === 'string')
// AssertionError: 表达式计算结果为假值:
//
//   assert.ok(typeof 123 === 'string')

assert.ok(false)
// AssertionError: 表达式计算结果为假值:
//
//   assert.ok(false)

assert.ok(0)
// AssertionError: 表达式计算结果为假值:
//
//   assert.ok(0)
js
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

// 在 repl 中:
assert.ok(typeof 123 === 'string')
// AssertionError: false == true

// 在文件中(例如 test.js):
assert.ok(typeof 123 === 'string')
// AssertionError: 表达式计算结果为假值:
//
//   assert.ok(typeof 123 === 'string')

assert.ok(false)
// AssertionError: 表达式计算结果为假值:
//
//   assert.ok(false)

assert.ok(0)
// AssertionError: 表达式计算结果为假值:
//
//   assert.ok(0)
js
import assert from 'node:assert/strict'

// 使用 `assert()` 的效果相同:
assert(0)
// AssertionError: 表达式计算结果为假值:
//
//   assert(0)
js
const assert = require('node:assert')

// 使用 `assert()` 的效果相同:
assert(0)
// AssertionError: 表达式计算结果为假值:
//
//   assert(0)

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

新增于: v10.0.0

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

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

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

如果指定,error 可以是 ClassRegExp,一个验证函数,一个将对其每个属性进行测试的对象,或者一个错误实例,将对其每个属性进行测试,包括不可枚举的 messagename 属性。

如果指定,message 将是 asyncFn 失败时拒绝提供的 AssertionError 的消息。

js
import assert from 'node:assert/strict'

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

;(async () => {
  await assert.rejects(
    async () => {
      throw new TypeError('Wrong value')
    },
    {
      name: 'TypeError',
      message: 'Wrong value',
    }
  )
})()
js
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
  }
)
js
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
    }
  )
})()
js
import assert from 'node:assert/strict'

assert.rejects(Promise.reject(new Error('Wrong value')), Error).then(() => {
  // ...
})
js
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])

[历史]

版本变更
v10.0.0使用的比较方式从严格相等更改为 Object.is()
v0.1.21新增于:v0.1.21

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

js
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 identical
js
const 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

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

[历史]

版本变更
v10.2.0error 参数现在可以是一个包含正则表达式的对象。
v9.9.0error 参数现在也可以是一个对象。
v4.2.0error 参数现在也可以是一个箭头函数。
v0.1.21新增于:v0.1.21

预期函数 fn 会抛出一个错误。

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

如果指定,message 将附加到 AssertionError 提供的消息中,如果 fn 调用未能抛出错误或错误验证失败。

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

js
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',
    },
    // 只会测试验证对象上的属性。
    // 使用嵌套对象需要所有属性都存在。否则
    // 验证将失败。
  }
)

// 使用正则表达式验证错误属性:
assert.throws(
  () => {
    throw err
  },
  {
    // `name` 和 `message` 属性是字符串,在这些属性上使用正则表达式将与字符串匹配。如果它们失败,则会抛出错误。
    name: /^TypeError$/,
    message: /Wrong/,
    foo: 'bar',
    info: {
      nested: true,
      // 不允许对嵌套属性使用正则表达式!
      baz: 'text',
    },
    // `reg` 属性包含一个正则表达式,只有当
    // 验证对象包含相同的正则表达式时,它才会通过。
    reg: /abc/i,
  }
)

// 由于不同的 `message` 和 `name` 属性而失败:
assert.throws(
  () => {
    const otherErr = new Error('Not found')
    // 将所有可枚举属性从 `err` 复制到 `otherErr`。
    for (const [key, value] of Object.entries(err)) {
      otherErr[key] = value
    }
    throw otherErr
  },
  // 使用错误作为验证对象时,也会检查错误的 `message` 和 `name` 属性。
  err
)
js
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',
    },
    // 只会测试验证对象上的属性。
    // 使用嵌套对象需要所有属性都存在。否则
    // 验证将失败。
  }
)

// 使用正则表达式验证错误属性:
assert.throws(
  () => {
    throw err
  },
  {
    // `name` 和 `message` 属性是字符串,在这些属性上使用正则表达式将与字符串匹配。如果它们失败,则会抛出错误。
    name: /^TypeError$/,
    message: /Wrong/,
    foo: 'bar',
    info: {
      nested: true,
      // 不允许对嵌套属性使用正则表达式!
      baz: 'text',
    },
    // `reg` 属性包含一个正则表达式,只有当
    // 验证对象包含相同的正则表达式时,它才会通过。
    reg: /abc/i,
  }
)

// 由于不同的 `message` 和 `name` 属性而失败:
assert.throws(
  () => {
    const otherErr = new Error('Not found')
    // 将所有可枚举属性从 `err` 复制到 `otherErr`。
    for (const [key, value] of Object.entries(err)) {
      otherErr[key] = value
    }
    throw otherErr
  },
  // 使用错误作为验证对象时,也会检查错误的 `message` 和 `name` 属性。
  err
)

使用构造函数验证 instanceof:

js
import assert from 'node:assert/strict'

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

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

使用 正则表达式 验证错误消息:

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

js
import assert from 'node:assert/strict'

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

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

自定义错误验证:

该函数必须返回 true 以指示所有内部验证已通过。否则,它将使用 AssertionError 失败。

js
import assert from 'node:assert/strict'

assert.throws(
  () => {
    throw new Error('Wrong value')
  },
  err => {
    assert(err instanceof Error)
    assert(/value/.test(err))
    // 避免从验证函数返回除 `true` 之外的任何内容。
    // 否则,不清楚验证的哪一部分失败了。相反,
    // 抛出一个关于失败的特定验证的错误(如本例所示),并向该错误添加尽可能多的有用的调试信息。
    return true
  },
  'unexpected error'
)
js
const assert = require('node:assert/strict')

assert.throws(
  () => {
    throw new Error('Wrong value')
  },
  err => {
    assert(err instanceof Error)
    assert(/value/.test(err))
    // 避免从验证函数返回除 `true` 之外的任何内容。
    // 否则,不清楚验证的哪一部分失败了。相反,
    // 抛出一个关于失败的特定验证的错误(如本例所示),并向该错误添加尽可能多的有用的调试信息。
    return true
  },
  'unexpected error'
)

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

js
import assert from 'node:assert/strict'

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

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

function notThrowing() {}

// 第二个参数是一个字符串,输入函数抛出了一个 Error。
// 第一个案例不会抛出,因为它与输入函数抛出的错误消息不匹配!
assert.throws(throwingFirst, 'Second')
// 在下一个示例中,消息没有比错误的消息更有益,并且由于不清楚用户是否打算实际匹配
// 错误消息,Node.js 抛出 `ERR_AMBIGUOUS_ARGUMENT` 错误。
assert.throws(throwingSecond, 'Second')
// TypeError [ERR_AMBIGUOUS_ARGUMENT]

// 只有在函数没有抛出异常时才使用字符串(作为消息):
assert.throws(notThrowing, 'Second')
// AssertionError [ERR_ASSERTION]: Missing expected exception: Second

// 如果打算匹配错误消息,请改用此方法:
// 它不会抛出,因为错误消息匹配。
assert.throws(throwingSecond, /Second$/)

// 如果错误消息不匹配,则会抛出 AssertionError。
assert.throws(throwingFirst, /Second$/)
// AssertionError [ERR_ASSERTION]
js
const assert = require('node:assert/strict')

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

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

function notThrowing() {}

// 第二个参数是一个字符串,输入函数抛出了一个 Error。
// 第一个案例不会抛出,因为它与输入函数抛出的错误消息不匹配!
assert.throws(throwingFirst, 'Second')
// 在下一个示例中,消息没有比错误的消息更有益,并且由于不清楚用户是否打算实际匹配
// 错误消息,Node.js 抛出 `ERR_AMBIGUOUS_ARGUMENT` 错误。
assert.throws(throwingSecond, 'Second')
// TypeError [ERR_AMBIGUOUS_ARGUMENT]

// 只有在函数没有抛出异常时才使用字符串(作为消息):
assert.throws(notThrowing, 'Second')
// AssertionError [ERR_ASSERTION]: Missing expected exception: Second

// 如果打算匹配错误消息,请改用此方法:
// 它不会抛出,因为错误消息匹配。
assert.throws(throwingSecond, /Second$/)

// 如果错误消息不匹配,则会抛出 AssertionError。
assert.throws(throwingFirst, /Second$/)
// AssertionError [ERR_ASSERTION]

由于容易混淆且容易出错的表示法,请避免使用字符串作为第二个参数。

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

新增于:v23.4.0

[稳定性:1 - 实验性]

稳定性:1 稳定性:1.0 - 早期开发

assert.partialDeepStrictEqual() 通过深度比较来断言actualexpected参数之间的等价性,确保expected参数中的所有属性都存在于actual参数中,且具有等效的值,不允许类型强制转换。与assert.deepStrictEqual()的主要区别在于,assert.partialDeepStrictEqual()不需要actual参数中的所有属性都存在于expected参数中。此方法应始终通过与assert.deepStrictEqual()相同的测试用例,作为其超集。

js
import assert from 'node:assert'

assert.partialDeepStrictEqual({ a: 1, b: 2 }, { a: 1, b: 2 })
// OK

assert.partialDeepStrictEqual({ a: { b: { c: 1 } } }, { a: { b: { c: 1 } } })
// OK

assert.partialDeepStrictEqual({ a: 1, b: 2, c: 3 }, { a: 1, b: 2 })
// OK

assert.partialDeepStrictEqual(new Set(['value1', 'value2']), new Set(['value1', 'value2']))
// OK

assert.partialDeepStrictEqual(new Map([['key1', 'value1']]), new Map([['key1', 'value1']]))
// OK

assert.partialDeepStrictEqual(new Uint8Array([1, 2, 3]), new Uint8Array([1, 2, 3]))
// OK

assert.partialDeepStrictEqual(/abc/, /abc/)
// OK

assert.partialDeepStrictEqual([{ a: 5 }, { b: 5 }], [{ a: 5 }])
// OK

assert.partialDeepStrictEqual(new Set([{ a: 1 }, { b: 1 }]), new Set([{ a: 1 }]))
// OK

assert.partialDeepStrictEqual(new Date(0), new Date(0))
// OK

assert.partialDeepStrictEqual({ a: 1 }, { a: 1, b: 2 })
// AssertionError

assert.partialDeepStrictEqual({ a: 1, b: '2' }, { a: 1, b: 2 })
// AssertionError

assert.partialDeepStrictEqual({ a: { b: 2 } }, { a: { b: '2' } })
// AssertionError
js
const assert = require('node:assert')

assert.partialDeepStrictEqual({ a: 1, b: 2 }, { a: 1, b: 2 })
// OK

assert.partialDeepStrictEqual({ a: { b: { c: 1 } } }, { a: { b: { c: 1 } } })
// OK

assert.partialDeepStrictEqual({ a: 1, b: 2, c: 3 }, { a: 1, b: 2 })
// OK

assert.partialDeepStrictEqual([{ a: 5 }, { b: 5 }], [{ a: 5 }])
// OK

assert.partialDeepStrictEqual(new Set([{ a: 1 }, { b: 1 }]), new Set([{ a: 1 }]))
// OK

assert.partialDeepStrictEqual({ a: 1 }, { a: 1, b: 2 })
// AssertionError

assert.partialDeepStrictEqual({ a: 1, b: '2' }, { a: 1, b: 2 })
// AssertionError

assert.partialDeepStrictEqual({ a: { b: 2 } }, { a: { b: '2' } })
// AssertionError