断言
源代码: 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()
。
在严格断言模式下,对象的错误消息会显示差异。在遗留断言模式下,对象的错误消息会显示对象,通常会被截断。
要使用严格断言模式:
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')
示例错误差异:
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_COLOR
或 NODE_DISABLE_COLORS
环境变量。这也会停用 REPL 中的颜色。有关终端环境中颜色支持的更多信息,请阅读 tty getColorDepth()
文档。
传统断言模式
传统断言模式在以下方法中使用==
运算符:
要使用传统断言模式:
import assert from 'node:assert'
const assert = require('node:assert')
传统断言模式可能会产生令人意外的结果,尤其是在使用assert.deepEqual()
时:
// WARNING: 在传统断言模式下,这不会抛出 AssertionError!
assert.deepEqual(/a/gi, new Date())
类:assert.AssertionError
- 继承自:<errors.Error>
指示断言失败。node:assert
模块抛出的所有错误都将是 AssertionError
类的实例。
new assert.AssertionError(options)
新增于:v0.1.21
options
<对象>
Error
的子类,指示断言失败。
所有实例都包含内置的 Error
属性(message
和 name
),以及:
actual
<任意> 设置为诸如assert.strictEqual()
之类方法的actual
参数。expected
<任意> 设置为诸如assert.strictEqual()
之类方法的expected
值。generatedMessage
<布尔值> 指示消息是自动生成的 (true
) 还是手动指定的。code
<字符串> 值始终为ERR_ASSERTION
,以表明该错误是断言错误。operator
<字符串> 设置为传入的操作符值。
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)
}
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.0 | assert.CallTracker 类已弃用,将在未来版本中移除。 |
v14.2.0, v12.19.0 | 新增于: v14.2.0, v12.19.0 |
此功能已弃用,将在未来版本中移除。请考虑使用替代方案,例如 mock
辅助函数。
new assert.CallTracker()
新增于: v14.2.0, v12.19.0
创建一个新的 CallTracker
对象,可用于跟踪函数被调用的次数。必须调用 tracker.verify()
才能进行验证。通常的做法是在 process.on('exit')
处理程序中调用它。
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()
})
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
fn
<Function> 默认值: 一个空操作函数。exact
<number> 默认值:1
。- 返回值: <Function> 一个包装
fn
的函数。
该包装函数预期被精确调用 exact
次。如果在调用 tracker.verify()
时,该函数没有被精确调用 exact
次,则 tracker.verify()
将抛出错误。
import assert from 'node:assert'
// 创建调用跟踪器。
const tracker = new assert.CallTracker()
function func() {}
// 返回一个包装 func() 的函数,该函数必须在 tracker.verify() 之前被精确调用指定次数。
const callsfunc = tracker.calls(func)
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
fn
<Function>- 返回:<Array> 包含对被追踪函数的所有调用的数组。
- 对象 <Object>
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')
// 创建调用追踪器。
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
- 返回值: <Array> 一个包含有关
tracker.calls()
返回的包装函数信息的对象数组。 - 对象 <Object>
数组包含有关预期调用次数和实际调用次数不相符的函数的信息。
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
// }
// ]
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
fn
<Function> 要重置的已跟踪函数。
重置调用跟踪器的调用。如果将已跟踪函数作为参数传递,则将重置其调用。如果未传递任何参数,则将重置所有已跟踪函数。
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)
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()
的函数列表,对于未被调用预期次数的函数将抛出错误。
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()
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 | 还比较 Set 和 Map 内容。 |
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 |
严格断言模式
传统断言模式
[稳定:3 - 传统]
稳定:3 稳定性:3 - 传统:请改用 assert.deepStrictEqual()
。
测试 actual
和 expected
参数之间的深度相等性。建议改用 assert.deepStrictEqual()
。assert.deepEqual()
可能会有令人意外的结果。
深度相等 意味着子对象的枚举“自身”属性也通过以下规则递归评估。
深度比较细节
- 原生值使用
==
运算符进行比较,NaN
除外。如果两侧都是NaN
,则将其视为相同。 - 对象的类型标签应该相同。
- 只考虑可枚举的“自身”属性。
Error
的名称、消息、原因和错误始终进行比较,即使这些不是可枚举属性。- 对象包装器 既作为对象又作为解包值进行比较。
Object
属性的比较顺序无关紧要。Map
的键和Set
的项的比较顺序无关紧要。- 当双方不同或双方都遇到循环引用时,递归停止。
- 实现不测试对象的
[[Prototype]]
。 - 不比较
Symbol
属性。 WeakMap
和WeakSet
的比较不依赖于它们的值,只依赖于它们的实例。RegExp
的 lastIndex、flags 和 source 始终进行比较,即使这些不是可枚举属性。
下面的例子不会抛出AssertionError
,因为原生值使用==
运算符进行比较。
import assert from 'node:assert'
// WARNING: 这不会抛出 AssertionError!
assert.deepEqual('+00000000', false)
const assert = require('node:assert')
// WARNING: 这不会抛出 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 = { __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 {}
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 | 也比较 Set 和 Map 的内容。 |
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 中添加 |
测试 actual
和 expected
参数之间的深度相等性。“深度”相等性意味着子对象的枚举“自身”属性也根据以下规则递归评估。
比较细节
- 使用
Object.is()
比较原始值。 - 对象的 类型标签 应该相同。
- 使用
===
运算符 比较对象的[[Prototype]]
。 - 只考虑 可枚举的“自身”属性。
- 始终比较
Error
的名称、消息、原因和错误,即使这些不是可枚举属性。也比较errors
。 - 也比较可枚举的自身
Symbol
属性。 - 同时将 对象包装器 作为对象和解包后的值进行比较。
- 对象属性的比较顺序无关紧要。
Map
的键和Set
的项的比较顺序无关紧要。- 当双方不同或双方遇到循环引用时,递归停止。
WeakMap
和WeakSet
的比较不依赖于它们的值。详情见下文。- 始终比较
RegExp
的 lastIndex、flags 和 source,即使这些不是可枚举属性。
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
// }
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
输入不匹配正则表达式。
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
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
<Function> | <Promise>error
<RegExp> | <Function>message
<string>
等待 asyncFn
promise,或者如果 asyncFn
是一个函数,则立即调用该函数并等待返回的 promise 完成。然后它将检查 promise 是否没有被拒绝。
如果 asyncFn
是一个函数并且它同步抛出错误,assert.doesNotReject()
将返回一个带有该错误的被拒绝的 Promise
。如果函数没有返回 promise,assert.doesNotReject()
将返回一个带有 ERR_INVALID_RETURN_VALUE
错误的被拒绝的 Promise
。在这两种情况下,都会跳过错误处理程序。
使用 assert.doesNotReject()
实际上并没有什么用,因为捕获拒绝然后再次拒绝它几乎没有好处。相反,考虑在不应该拒绝的特定代码路径旁边添加注释,并使错误消息尽可能具有表达性。
如果指定,error
可以是 Class
,RegExp
或一个验证函数。参见 assert.throws()
获取更多细节。
除了异步性质之外,等待完成的行为与 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])
[历史]
版本 | 变更 |
---|---|
v5.11.0, v4.4.5 | message 参数现在已生效。 |
v4.2.0 | error 参数现在可以是箭头函数。 |
v0.1.21 | 新增于:v0.1.21 |
断言函数 fn
不抛出错误。
使用 assert.doesNotThrow()
实际上并没有什么用处,因为捕获错误然后重新抛出它没有任何好处。 相反,考虑在不应该抛出异常的特定代码路径旁边添加注释,并使错误消息尽可能具有表达性。
调用 assert.doesNotThrow()
时,它将立即调用 fn
函数。
如果抛出错误,并且其类型与 error
参数指定的类型相同,则会抛出 AssertionError
。如果错误的类型不同,或者 error
参数未定义,则错误将传播回调用方。
如果指定,error
可以是 类
、正则表达式
或验证函数。有关更多详细信息,请参阅 assert.throws()
。
例如,以下代码将抛出 TypeError
,因为断言中没有匹配的错误类型:
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
:
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
消息:
import assert from 'node:assert/strict'
assert.doesNotThrow(
() => {
throw new TypeError('Wrong value')
},
/Wrong value/,
'Whoops'
)
// 抛出:AssertionError: Got unwanted exception: Whoops
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()
。
使用 ==
运算符 测试 actual
和 expected
参数之间的浅层、强制类型转换相等性。NaN
具有特殊处理,如果两侧都是 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 } }
如果值不相等,则会抛出 AssertionError
,其 message
属性设置为 message
参数的值。如果 message
参数未定义,则会分配默认错误消息。如果 message
参数是 Error
的实例,则会抛出它而不是 AssertionError
。
assert.fail([message])
新增于: v0.1.21
抛出一个带有提供的错误消息或默认错误消息的 AssertionError
。如果 message
参数是 Error
的实例,则会抛出它而不是 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 array
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 |
actual
<任意>expected
<任意>message
<字符串> | <错误>operator
<字符串> 默认值:'!='
stackStartFn
<函数> 默认值:assert.fail
如果 message
为假值,则错误消息设置为 actual
和 expected
的值,由提供的 operator
分隔。如果只提供 actual
和 expected
两个参数,则 operator
将默认为 '!='
。如果 message
作为第三个参数提供,它将用作错误消息,其他参数将作为属性存储在抛出的对象上。如果提供了 stackStartFn
,则该函数以上的所有堆栈帧都将从堆栈跟踪中移除(参见 Error.captureStackTrace
)。如果没有给出任何参数,将使用默认消息 Failed
。
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
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
在最后三种情况下,actual
、expected
和 operator
对错误消息没有影响。
stackStartFn
用于截断异常堆栈跟踪的示例:
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)
[历史]
版本 | 变更 |
---|---|
v10.0.0 | 不再抛出原始错误,而是将其包装到一个包含完整堆栈跟踪的 [AssertionError ][] 中。 |
v10.0.0 | value 现在只能是 undefined 或 null 。在此之前,所有假值都与 null 一样处理,不会抛出异常。 |
v0.1.97 | v0.1.97 版本新增 |
value
<任何>
如果 value
不是 undefined
或 null
,则抛出 value
。这在测试回调中的 error
参数时非常有用。堆栈跟踪包含从传递到 ifError()
的错误中获取的所有帧,包括 ifError()
本身可能的新帧。
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
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
输入与正则表达式匹配。
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
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 | 也比较 Set 和 Map 内容。 |
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()
的反义词。
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
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.0 | NaN 现在使用 SameValueZero 进行比较。 |
v9.0.0 | Error 的名称和消息现在被正确比较。 |
v8.0.0 | Set 和 Map 的内容也被比较。 |
v6.1.0 | 现在可以使用包含循环引用的对象作为输入。 |
v6.4.0, v4.7.1 | 现在正确处理类型化数组切片。 |
v5.10.1, v4.4.3 | 正确处理非 Uint8Array 类型化数组。 |
v1.2.0 | 添加于:v1.2.0 |
测试深度严格不等式。与 assert.deepStrictEqual()
相反。
import assert from 'node:assert/strict'
assert.notDeepStrictEqual({ a: 1 }, { a: '1' })
// OK
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 |
严格断言模式
传统断言模式
[稳定:3 - 传统]
稳定:3 稳定性:3 - 传统:请改用 assert.notStrictEqual()
。
使用 !=
运算符 测试浅层、强制不等式。NaN
将被特殊处理,如果双方都是 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
。
assert.notStrictEqual(actual, expected[, message])
[历史]
版本 | 变更 |
---|---|
v10.0.0 | 使用的比较方式从严格相等更改为 Object.is() 。 |
v0.1.21 | v0.1.21 版本中添加 |
根据 Object.is()
确定 actual
和 expected
参数之间的严格不等性。
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
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.0 | assert.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
中,错误消息将与在文件中抛出的错误消息不同!请参见下面的详细信息。
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)
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)
import assert from 'node:assert/strict'
// 使用 `assert()` 的效果相同:
assert(0)
// AssertionError: 表达式计算结果为假值:
//
// assert(0)
const assert = require('node:assert')
// 使用 `assert()` 的效果相同:
assert(0)
// AssertionError: 表达式计算结果为假值:
//
// assert(0)
assert.rejects(asyncFn[, error][, message])
新增于: v10.0.0
asyncFn
<Function> | <Promise>error
<RegExp> | <Function> | <Object> | <Error>message
<string>
等待 asyncFn
Promise,或者如果 asyncFn
是一个函数,则立即调用该函数并等待返回的 Promise 完成。然后,它将检查该 Promise 是否被拒绝。
如果 asyncFn
是一个函数并且它同步抛出一个错误,assert.rejects()
将返回一个带有该错误的被拒绝的 Promise
。如果该函数没有返回 Promise,assert.rejects()
将返回一个带有 ERR_INVALID_RETURN_VALUE
错误的被拒绝的 Promise
。在这两种情况下,都会跳过错误处理程序。
除了异步等待完成之外,其行为与 assert.throws()
完全相同。
如果指定,error
可以是 Class
,RegExp
,一个验证函数,一个将对其每个属性进行测试的对象,或者一个错误实例,将对其每个属性进行测试,包括不可枚举的 message
和 name
属性。
如果指定,message
将是 asyncFn
失败时拒绝提供的 AssertionError
的消息。
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])
[历史]
版本 | 变更 |
---|---|
v10.0.0 | 使用的比较方式从严格相等更改为 Object.is() 。 |
v0.1.21 | 新增于:v0.1.21 |
根据 Object.is()
判断 actual
和 expected
参数是否严格相等。
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
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.0 | error 参数现在可以是一个包含正则表达式的对象。 |
v9.9.0 | error 参数现在也可以是一个对象。 |
v4.2.0 | error 参数现在也可以是一个箭头函数。 |
v0.1.21 | 新增于:v0.1.21 |
预期函数 fn
会抛出一个错误。
如果指定,error
可以是 类
,正则表达式
,一个验证函数,一个验证对象(其中每个属性都将进行严格的深度相等性测试),或者一个错误实例(其中每个属性都将进行严格的深度相等性测试,包括不可枚举的 message
和 name
属性)。使用对象时,在针对字符串属性进行验证时,也可以使用正则表达式。请参见下面的示例。
如果指定,message
将附加到 AssertionError
提供的消息中,如果 fn
调用未能抛出错误或错误验证失败。
自定义验证对象/错误实例:
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
)
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:
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)
使用 正则表达式
验证错误消息:
使用正则表达式会对错误对象运行 .toString
,因此也会包含错误名称。
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$/)
自定义错误验证:
该函数必须返回 true
以指示所有内部验证已通过。否则,它将使用 AssertionError
失败。
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'
)
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
错误。如果使用字符串作为第二个参数,请仔细阅读下面的示例:
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]
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
assert.partialDeepStrictEqual()
通过深度比较来断言actual
和expected
参数之间的等价性,确保expected
参数中的所有属性都存在于actual
参数中,且具有等效的值,不允许类型强制转换。与assert.deepStrictEqual()
的主要区别在于,assert.partialDeepStrictEqual()
不需要actual
参数中的所有属性都存在于expected
参数中。此方法应始终通过与assert.deepStrictEqual()
相同的测试用例,作为其超集。
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
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