node/doc/api/assert.md
Ruben Bridgewater d3f79aa65d
assert: allow printf-style messages as assertion error
Also add functions as allowed message input.
This allows to have leavy message computation to become cheaper.

PR-URL: https://github.com/nodejs/node/pull/58849
Reviewed-By: Marco Ippolito <marcoippolito54@gmail.com>
Reviewed-By: Michaël Zasso <targos@protonmail.com>
Reviewed-By: Rafael Gonzaga <rafael.nunu@hotmail.com>
2025-10-17 20:15:17 +00:00

2549 lines
69 KiB
Markdown

# Assert
<!--introduced_in=v0.1.21-->
> Stability: 2 - Stable
<!-- source_link=lib/assert.js -->
The `node:assert` module provides a set of assertion functions for verifying
invariants.
## Strict assertion mode
<!-- YAML
added: v9.9.0
changes:
- version: v15.0.0
pr-url: https://github.com/nodejs/node/pull/34001
description: Exposed as `require('node:assert/strict')`.
- version:
- v13.9.0
- v12.16.2
pr-url: https://github.com/nodejs/node/pull/31635
description: Changed "strict mode" to "strict assertion mode" and "legacy
mode" to "legacy assertion mode" to avoid confusion with the
more usual meaning of "strict mode".
- version: v9.9.0
pr-url: https://github.com/nodejs/node/pull/17615
description: Added error diffs to the strict assertion mode.
- version: v9.9.0
pr-url: https://github.com/nodejs/node/pull/17002
description: Added strict assertion mode to the assert module.
-->
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.
### Message parameter semantics
For assertion methods that accept an optional `message` parameter, the message
may be provided in one of the following forms:
* **string**: Used as-is. If additional arguments are supplied after the
`message` string, they are treated as printf-like substitutions (see
[`util.format()`][]).
* **Error**: If an `Error` instance is provided as `message`, that error is
thrown directly instead of an `AssertionError`.
* **function**: A function of the form `(actual, expected) => string`. It is
called only when the assertion fails and should return a string to be used as
the error message. Non-string return values are ignored and the default
message is used instead.
If additional arguments are passed along with an `Error` or a function as
`message`, the call is rejected with `ERR_AMBIGUOUS_ARGUMENT`.
If the first item is neither a string, `Error`, nor function, `ERR_INVALID_ARG_TYPE`
is thrown.
To use strict assertion mode:
```mjs
import { strict as assert } from 'node:assert';
```
```cjs
const assert = require('node:assert').strict;
```
```mjs
import assert from 'node:assert/strict';
```
```cjs
const assert = require('node:assert/strict');
```
Example error diff:
```mjs
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
// ]
```
```cjs
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
// ]
```
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:
* [`assert.deepEqual()`][]
* [`assert.equal()`][]
* [`assert.notDeepEqual()`][]
* [`assert.notEqual()`][]
To use legacy assertion mode:
```mjs
import assert from 'node:assert';
```
```cjs
const assert = require('node:assert');
```
Legacy assertion mode may have surprising results, especially when using
[`assert.deepEqual()`][]:
```cjs
// WARNING: This does not throw an AssertionError in legacy assertion mode!
assert.deepEqual(/a/gi, new Date());
```
## Class: `assert.AssertionError`
* Extends: {errors.Error}
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)`
<!-- YAML
added: v0.1.21
-->
* `options` {Object}
* `message` {string} If provided, the error message is set to this value.
* `actual` {any} The `actual` property on the error instance.
* `expected` {any} The `expected` property on the error instance.
* `operator` {string} The `operator` property on the error instance.
* `stackStartFn` {Function} If provided, the generated stack trace omits
frames before this function.
* `diff` {string} If set to `'full'`, shows the full diff in assertion errors. Defaults to `'simple'`.
Accepted values: `'simple'`, `'full'`.
A subclass of {Error} that indicates the failure of an assertion.
All instances contain the built-in `Error` properties (`message` and `name`)
and:
* `actual` {any} Set to the `actual` argument for methods such as
[`assert.strictEqual()`][].
* `expected` {any} Set to the `expected` value for methods such as
[`assert.strictEqual()`][].
* `generatedMessage` {boolean} Indicates if the message was auto-generated
(`true`) or not.
* `code` {string} Value is always `ERR_ASSERTION` to show that the error is an
assertion error.
* `operator` {string} Set to the passed in operator value.
```mjs
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);
}
```
```cjs
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);
}
```
## Class: `assert.Assert`
<!-- YAML
added:
- v24.6.0
- v22.19.0
-->
The `Assert` class allows creating independent assertion instances with custom options.
### `new assert.Assert([options])`
<!-- YAML
changes:
- version: v24.9.0
pr-url: https://github.com/nodejs/node/pull/59762
description: Added `skipPrototype` option.
-->
* `options` {Object}
* `diff` {string} If set to `'full'`, shows the full diff in assertion errors. Defaults to `'simple'`.
Accepted values: `'simple'`, `'full'`.
* `strict` {boolean} If set to `true`, non-strict methods behave like their
corresponding strict methods. Defaults to `true`.
* `skipPrototype` {boolean} If set to `true`, skips prototype and constructor
comparison in deep equality checks. Defaults to `false`.
Creates a new assertion instance. The `diff` option controls the verbosity of diffs in assertion error messages.
```js
const { Assert } = require('node:assert');
const assertInstance = new Assert({ diff: 'full' });
assertInstance.deepStrictEqual({ a: 1 }, { a: 2 });
// Shows a full diff in the error message.
```
**Important**: When destructuring assertion methods from an `Assert` instance,
the methods lose their connection to the instance's configuration options (such
as `diff`, `strict`, and `skipPrototype` settings).
The destructured methods will fall back to default behavior instead.
```js
const myAssert = new Assert({ diff: 'full' });
// This works as expected - uses 'full' diff
myAssert.strictEqual({ a: 1 }, { b: { c: 1 } });
// This loses the 'full' diff setting - falls back to default 'simple' diff
const { strictEqual } = myAssert;
strictEqual({ a: 1 }, { b: { c: 1 } });
```
The `skipPrototype` option affects all deep equality methods:
```js
class Foo {
constructor(a) {
this.a = a;
}
}
class Bar {
constructor(a) {
this.a = a;
}
}
const foo = new Foo(1);
const bar = new Bar(1);
// Default behavior - fails due to different constructors
const assert1 = new Assert();
assert1.deepStrictEqual(foo, bar); // AssertionError
// Skip prototype comparison - passes if properties are equal
const assert2 = new Assert({ skipPrototype: true });
assert2.deepStrictEqual(foo, bar); // OK
```
When destructured, methods lose access to the instance's `this` context and revert to default assertion behavior
(diff: 'simple', non-strict mode).
To maintain custom options when using destructured methods, avoid
destructuring and call methods directly on the instance.
## `assert(value[, message])`
<!-- YAML
added: v0.5.9
changes:
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/58849
description: Message may now be a `printf`-like format string or function.
-->
* `value` {any} The input that is checked for being truthy.
* `message` {string|Error|Function}
An alias of [`assert.ok()`][].
## `assert.deepEqual(actual, expected[, message])`
<!-- YAML
added: v0.1.21
changes:
- version: v25.0.0
pr-url: https://github.com/nodejs/node/pull/59448
description: Promises are not considered equal anymore if they are not of
the same instance.
- version: v25.0.0
pr-url: https://github.com/nodejs/node/pull/57627
description: Invalid dates are now considered equal.
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/58849
description: Message may now be a `printf`-like format string or function.
- version: v24.0.0
pr-url: https://github.com/nodejs/node/pull/57622
description: Recursion now stops when either side encounters a circular
reference.
- version:
- v22.2.0
- v20.15.0
pr-url: https://github.com/nodejs/node/pull/51805
description: Error cause and errors properties are now compared as well.
- version: v18.0.0
pr-url: https://github.com/nodejs/node/pull/41020
description: Regular expressions lastIndex property is now compared as well.
- version:
- v16.0.0
- v14.18.0
pr-url: https://github.com/nodejs/node/pull/38113
description: In Legacy assertion mode, changed status from Deprecated to
Legacy.
- version: v14.0.0
pr-url: https://github.com/nodejs/node/pull/30766
description: NaN is now treated as being identical if both sides are
NaN.
- version: v12.0.0
pr-url: https://github.com/nodejs/node/pull/25008
description: The type tags are now properly compared and there are a couple
minor comparison adjustments to make the check less surprising.
- version: v9.0.0
pr-url: https://github.com/nodejs/node/pull/15001
description: The `Error` names and messages are now properly compared.
- version: v8.0.0
pr-url: https://github.com/nodejs/node/pull/12142
description: The `Set` and `Map` content is also compared.
- version:
- v6.4.0
- v4.7.1
pr-url: https://github.com/nodejs/node/pull/8002
description: Typed array slices are handled correctly now.
- version:
- v6.1.0
- v4.5.0
pr-url: https://github.com/nodejs/node/pull/6432
description: Objects with circular references can be used as inputs now.
- version:
- v5.10.1
- v4.4.3
pr-url: https://github.com/nodejs/node/pull/5910
description: Handle non-`Uint8Array` typed arrays correctly.
-->
* `actual` {any}
* `expected` {any}
* `message` {string|Error|Function}
**Strict assertion mode**
An alias of [`assert.deepStrictEqual()`][].
**Legacy assertion mode**
> Stability: 3 - Legacy: Use [`assert.deepStrictEqual()`][] instead.
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
* Primitive values are compared with the [`==` operator][],
with the exception of {NaN}. It is treated as being identical in case
both sides are {NaN}.
* [Type tags][Object.prototype.toString()] of objects should be the same.
* Only [enumerable "own" properties][] are considered.
* {Error} names, messages, causes, and errors are always compared,
even if these are not enumerable properties.
* [Object wrappers][] are compared both as objects and unwrapped values.
* `Object` properties are compared unordered.
* {Map} keys and {Set} items are compared unordered.
* Recursion stops when both sides differ or either side encounters a circular
reference.
* Implementation does not test the [`[[Prototype]]`][prototype-spec] of
objects.
* {Symbol} properties are not compared.
* {WeakMap}, {WeakSet} and {Promise} instances are **not** compared
structurally. They are only equal if they reference the same object. Any
comparison between different `WeakMap`, `WeakSet`, or `Promise` instances
will result in inequality, even if they contain the same content.
* {RegExp} lastIndex, flags, and source are always compared, even if these
are not enumerable properties.
The following example does not throw an [`AssertionError`][] because the
primitives are compared using the [`==` operator][].
```mjs
import assert from 'node:assert';
// WARNING: This does not throw an AssertionError!
assert.deepEqual('+00000000', false);
```
```cjs
const assert = require('node:assert');
// WARNING: This does not throw an AssertionError!
assert.deepEqual('+00000000', false);
```
"Deep" equality means that the enumerable "own" properties of child objects
are evaluated also:
```mjs
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
// 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 {}
```
```cjs
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
// 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 {}
```
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 {Error} then it will be thrown instead of the
[`AssertionError`][].
## `assert.deepStrictEqual(actual, expected[, message])`
<!-- YAML
added: v1.2.0
changes:
- version: v25.0.0
pr-url: https://github.com/nodejs/node/pull/59448
description: Promises are not considered equal anymore if they are not of
the same instance.
- version: v25.0.0
pr-url: https://github.com/nodejs/node/pull/57627
description: Invalid dates are now considered equal.
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/58849
description: Message may now be a `printf`-like format string or function.
- version: v24.0.0
pr-url: https://github.com/nodejs/node/pull/57622
description: Recursion now stops when either side encounters a circular
reference.
- version:
- v22.2.0
- v20.15.0
pr-url: https://github.com/nodejs/node/pull/51805
description: Error cause and errors properties are now compared as well.
- version: v18.0.0
pr-url: https://github.com/nodejs/node/pull/41020
description: Regular expressions lastIndex property is now compared as well.
- version: v9.0.0
pr-url: https://github.com/nodejs/node/pull/15169
description: Enumerable symbol properties are now compared.
- version: v9.0.0
pr-url: https://github.com/nodejs/node/pull/15036
description: The `NaN` is now compared using the
[SameValueZero](https://tc39.github.io/ecma262/#sec-samevaluezero)
comparison.
- version: v8.5.0
pr-url: https://github.com/nodejs/node/pull/15001
description: The `Error` names and messages are now properly compared.
- version: v8.0.0
pr-url: https://github.com/nodejs/node/pull/12142
description: The `Set` and `Map` content is also compared.
- version:
- v6.4.0
- v4.7.1
pr-url: https://github.com/nodejs/node/pull/8002
description: Typed array slices are handled correctly now.
- version: v6.1.0
pr-url: https://github.com/nodejs/node/pull/6432
description: Objects with circular references can be used as inputs now.
- version:
- v5.10.1
- v4.4.3
pr-url: https://github.com/nodejs/node/pull/5910
description: Handle non-`Uint8Array` typed arrays correctly.
-->
* `actual` {any}
* `expected` {any}
* `message` {string|Error|Function}
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
* Primitive values are compared using [`Object.is()`][].
* [Type tags][Object.prototype.toString()] of objects should be the same.
* [`[[Prototype]]`][prototype-spec] of objects are compared using
the [`===` operator][].
* Only [enumerable "own" properties][] are considered.
* {Error} names, messages, causes, and errors are always compared,
even if these are not enumerable properties.
`errors` is also compared.
* Enumerable own {Symbol} properties are compared as well.
* [Object wrappers][] are compared both as objects and unwrapped values.
* `Object` properties are compared unordered.
* {Map} keys and {Set} items are compared unordered.
* Recursion stops when both sides differ or either side encounters a circular
reference.
* {WeakMap}, {WeakSet} and {Promise} instances are **not** compared
structurally. They are only equal if they reference the same object. Any
comparison between different `WeakMap`, `WeakSet`, or `Promise` instances
will result in inequality, even if they contain the same content.
* {RegExp} lastIndex, flags, and source are always compared, even if these
are not enumerable properties.
```mjs
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 obj = {};
weakMap1.set(obj, 'value');
weakMap2.set(obj, 'value');
// Comparing different instances fails, even with same contents
assert.deepStrictEqual(weakMap1, weakMap2);
// AssertionError: Values have same structure but are not reference-equal:
//
// WeakMap {
// <items unknown>
// }
// Comparing the same instance to itself succeeds
assert.deepStrictEqual(weakMap1, weakMap1);
// OK
const weakSet1 = new WeakSet();
const weakSet2 = new WeakSet();
weakSet1.add(obj);
weakSet2.add(obj);
// Comparing different instances fails, even with same contents
assert.deepStrictEqual(weakSet1, weakSet2);
// AssertionError: Values have same structure but are not reference-equal:
// + actual - expected
//
// WeakSet {
// <items unknown>
// }
// Comparing the same instance to itself succeeds
assert.deepStrictEqual(weakSet1, weakSet1);
// OK
```
```cjs
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 obj = {};
weakMap1.set(obj, 'value');
weakMap2.set(obj, 'value');
// Comparing different instances fails, even with same contents
assert.deepStrictEqual(weakMap1, weakMap2);
// AssertionError: Values have same structure but are not reference-equal:
//
// WeakMap {
// <items unknown>
// }
// Comparing the same instance to itself succeeds
assert.deepStrictEqual(weakMap1, weakMap1);
// OK
const weakSet1 = new WeakSet();
const weakSet2 = new WeakSet();
weakSet1.add(obj);
weakSet2.add(obj);
// Comparing different instances fails, even with same contents
assert.deepStrictEqual(weakSet1, weakSet2);
// AssertionError: Values have same structure but are not reference-equal:
// + actual - expected
//
// WeakSet {
// <items unknown>
// }
// Comparing the same instance to itself succeeds
assert.deepStrictEqual(weakSet1, weakSet1);
// OK
```
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 {Error} then it will be thrown instead of the
`AssertionError`.
## `assert.doesNotMatch(string, regexp[, message])`
<!-- YAML
added:
- v13.6.0
- v12.16.0
changes:
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/58849
description: Message may now be a `printf`-like format string or function.
- version: v16.0.0
pr-url: https://github.com/nodejs/node/pull/38111
description: This API is no longer experimental.
-->
* `string` {string}
* `regexp` {RegExp}
* `message` {string|Error|Function}
Expects the `string` input not to match the regular expression.
```mjs
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
```
```cjs
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
```
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 {Error} then it will be thrown instead of the
[`AssertionError`][].
## `assert.doesNotReject(asyncFn[, error][, message])`
<!-- YAML
added: v10.0.0
-->
* `asyncFn` {Function|Promise}
* `error` {RegExp|Function}
* `message` {string}
* Returns: {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.
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.
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.
If specified, `error` can be a [`Class`][], {RegExp} or a validation
function. See [`assert.throws()`][] for more details.
Besides the async nature to await the completion behaves identically to
[`assert.doesNotThrow()`][].
```mjs
import assert from 'node:assert/strict';
await assert.doesNotReject(
async () => {
throw new TypeError('Wrong value');
},
SyntaxError,
);
```
```cjs
const assert = require('node:assert/strict');
(async () => {
await assert.doesNotReject(
async () => {
throw new TypeError('Wrong value');
},
SyntaxError,
);
})();
```
```mjs
import assert from 'node:assert/strict';
assert.doesNotReject(Promise.reject(new TypeError('Wrong value')))
.then(() => {
// ...
});
```
```cjs
const assert = require('node:assert/strict');
assert.doesNotReject(Promise.reject(new TypeError('Wrong value')))
.then(() => {
// ...
});
```
## `assert.doesNotThrow(fn[, error][, message])`
<!-- YAML
added: v0.1.21
changes:
- version:
- v5.11.0
- v4.4.5
pr-url: https://github.com/nodejs/node/pull/2407
description: The `message` parameter is respected now.
- version: v4.2.0
pr-url: https://github.com/nodejs/node/pull/3276
description: The `error` parameter can now be an arrow function.
-->
* `fn` {Function}
* `error` {RegExp|Function}
* `message` {string}
Asserts that the function `fn` does not throw an error.
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.
When `assert.doesNotThrow()` is called, it will immediately call the `fn`
function.
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.
If specified, `error` can be a [`Class`][], {RegExp}, or a validation
function. See [`assert.throws()`][] for more details.
The following, for instance, will throw the {TypeError} because there is no
matching error type in the assertion:
```mjs
import assert from 'node:assert/strict';
assert.doesNotThrow(
() => {
throw new TypeError('Wrong value');
},
SyntaxError,
);
```
```cjs
const assert = require('node:assert/strict');
assert.doesNotThrow(
() => {
throw new TypeError('Wrong value');
},
SyntaxError,
);
```
However, the following will result in an [`AssertionError`][] with the message
'Got unwanted exception...':
```mjs
import assert from 'node:assert/strict';
assert.doesNotThrow(
() => {
throw new TypeError('Wrong value');
},
TypeError,
);
```
```cjs
const assert = require('node:assert/strict');
assert.doesNotThrow(
() => {
throw new TypeError('Wrong value');
},
TypeError,
);
```
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:
```mjs
import assert from 'node:assert/strict';
assert.doesNotThrow(
() => {
throw new TypeError('Wrong value');
},
/Wrong value/,
'Whoops',
);
// Throws: AssertionError: Got unwanted exception: Whoops
```
```cjs
const 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])`
<!-- YAML
added: v0.1.21
changes:
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/58849
description: Message may now be a `printf`-like format string or function.
- version:
- v16.0.0
- v14.18.0
pr-url: https://github.com/nodejs/node/pull/38113
description: In Legacy assertion mode, changed status from Deprecated to
Legacy.
- version: v14.0.0
pr-url: https://github.com/nodejs/node/pull/30766
description: NaN is now treated as being identical if both sides are
NaN.
-->
* `actual` {any}
* `expected` {any}
* `message` {string|Error|Function}
**Strict assertion mode**
An alias of [`assert.strictEqual()`][].
**Legacy assertion mode**
> Stability: 3 - Legacy: Use [`assert.strictEqual()`][] instead.
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`.
```mjs
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 } }
```
```cjs
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 } }
```
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 {Error} then it will be thrown instead of the
`AssertionError`.
## `assert.fail([message])`
<!-- YAML
added: v0.1.21
-->
* `message` {string|Error} **Default:** `'Failed'`
Throws an [`AssertionError`][] with the provided error message or a default
error message. If the `message` parameter is an instance of {Error} then
it will be thrown instead of the [`AssertionError`][].
```mjs
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
```
```cjs
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.ifError(value)`
<!-- YAML
added: v0.1.97
changes:
- version: v10.0.0
pr-url: https://github.com/nodejs/node/pull/18247
description: Instead of throwing the original error it is now wrapped into
an [`AssertionError`][] that contains the full stack trace.
- version: v10.0.0
pr-url: https://github.com/nodejs/node/pull/18247
description: Value may now only be `undefined` or `null`. Before all falsy
values were handled the same as `null` and did not throw.
-->
* `value` {any}
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.
```mjs
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 errorFrame
```
```cjs
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
// 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])`
<!-- YAML
added:
- v13.6.0
- v12.16.0
changes:
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/58849
description: Message may now be a `printf`-like format string or function.
- version: v16.0.0
pr-url: https://github.com/nodejs/node/pull/38111
description: This API is no longer experimental.
-->
* `string` {string}
* `regexp` {RegExp}
* `message` {string|Error|Function}
Expects the `string` input to match the regular expression.
```mjs
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/);
// OK
```
```cjs
const 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
```
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 {Error} then it will be thrown instead of the
[`AssertionError`][].
## `assert.notDeepEqual(actual, expected[, message])`
<!-- YAML
added: v0.1.21
changes:
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/58849
description: Message may now be a `printf`-like format string or function.
- version:
- v16.0.0
- v14.18.0
pr-url: https://github.com/nodejs/node/pull/38113
description: In Legacy assertion mode, changed status from Deprecated to
Legacy.
- version: v14.0.0
pr-url: https://github.com/nodejs/node/pull/30766
description: NaN is now treated as being identical if both sides are
NaN.
- version: v9.0.0
pr-url: https://github.com/nodejs/node/pull/15001
description: The `Error` names and messages are now properly compared.
- version: v8.0.0
pr-url: https://github.com/nodejs/node/pull/12142
description: The `Set` and `Map` content is also compared.
- version:
- v6.4.0
- v4.7.1
pr-url: https://github.com/nodejs/node/pull/8002
description: Typed array slices are handled correctly now.
- version:
- v6.1.0
- v4.5.0
pr-url: https://github.com/nodejs/node/pull/6432
description: Objects with circular references can be used as inputs now.
- version:
- v5.10.1
- v4.4.3
pr-url: https://github.com/nodejs/node/pull/5910
description: Handle non-`Uint8Array` typed arrays correctly.
-->
* `actual` {any}
* `expected` {any}
* `message` {string|Error|Function}
**Strict assertion mode**
An alias of [`assert.notDeepStrictEqual()`][].
**Legacy assertion mode**
> Stability: 3 - Legacy: Use [`assert.notDeepStrictEqual()`][] instead.
Tests for any deep inequality. Opposite of [`assert.deepEqual()`][].
```mjs
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
```
```cjs
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
```
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 {Error} then it will be thrown
instead of the `AssertionError`.
## `assert.notDeepStrictEqual(actual, expected[, message])`
<!-- YAML
added: v1.2.0
changes:
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/58849
description: Message may now be a `printf`-like format string or function.
- version: v9.0.0
pr-url: https://github.com/nodejs/node/pull/15398
description: The `-0` and `+0` are not considered equal anymore.
- version: v9.0.0
pr-url: https://github.com/nodejs/node/pull/15036
description: The `NaN` is now compared using the
[SameValueZero](https://tc39.github.io/ecma262/#sec-samevaluezero)
comparison.
- version: v9.0.0
pr-url: https://github.com/nodejs/node/pull/15001
description: The `Error` names and messages are now properly compared.
- version: v8.0.0
pr-url: https://github.com/nodejs/node/pull/12142
description: The `Set` and `Map` content is also compared.
- version:
- v6.4.0
- v4.7.1
pr-url: https://github.com/nodejs/node/pull/8002
description: Typed array slices are handled correctly now.
- version: v6.1.0
pr-url: https://github.com/nodejs/node/pull/6432
description: Objects with circular references can be used as inputs now.
- version:
- v5.10.1
- v4.4.3
pr-url: https://github.com/nodejs/node/pull/5910
description: Handle non-`Uint8Array` typed arrays correctly.
-->
* `actual` {any}
* `expected` {any}
* `message` {string|Error|Function}
Tests for deep strict inequality. Opposite of [`assert.deepStrictEqual()`][].
```mjs
import assert from 'node:assert/strict';
assert.notDeepStrictEqual({ a: 1 }, { a: '1' });
// OK
```
```cjs
const assert = require('node:assert/strict');
assert.notDeepStrictEqual({ a: 1 }, { a: '1' });
// OK
```
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 {Error} then it will be thrown
instead of the [`AssertionError`][].
## `assert.notEqual(actual, expected[, message])`
<!-- YAML
added: v0.1.21
changes:
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/58849
description: Message may now be a `printf`-like format string or function.
- version:
- v16.0.0
- v14.18.0
pr-url: https://github.com/nodejs/node/pull/38113
description: In Legacy assertion mode, changed status from Deprecated to
Legacy.
- version: v14.0.0
pr-url: https://github.com/nodejs/node/pull/30766
description: NaN is now treated as being identical if both sides are
NaN.
-->
* `actual` {any}
* `expected` {any}
* `message` {string|Error|Function}
**Strict assertion mode**
An alias of [`assert.notStrictEqual()`][].
**Legacy assertion mode**
> Stability: 3 - Legacy: Use [`assert.notStrictEqual()`][] instead.
Tests shallow, coercive inequality with the [`!=` operator][]. `NaN` is
specially handled and treated as being identical if both sides are `NaN`.
```mjs
import assert from 'node:assert';
assert.notEqual(1, 2);
// OK
assert.notEqual(1, 1);
// AssertionError: 1 != 1
assert.notEqual(1, '1');
// AssertionError: 1 != '1'
```
```cjs
const assert = require('node:assert');
assert.notEqual(1, 2);
// OK
assert.notEqual(1, 1);
// AssertionError: 1 != 1
assert.notEqual(1, '1');
// AssertionError: 1 != '1'
```
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 {Error} then it will be thrown instead of the
`AssertionError`.
## `assert.notStrictEqual(actual, expected[, message])`
<!-- YAML
added: v0.1.21
changes:
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/58849
description: Message may now be a `printf`-like format string or function.
- version: v10.0.0
pr-url: https://github.com/nodejs/node/pull/17003
description: Used comparison changed from Strict Equality to `Object.is()`.
-->
* `actual` {any}
* `expected` {any}
* `message` {string|Error|Function}
Tests strict inequality between the `actual` and `expected` parameters as
determined by [`Object.is()`][].
```mjs
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
```
```cjs
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
```
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 {Error} then it will be thrown
instead of the `AssertionError`.
## `assert.ok(value[, message])`
<!-- YAML
added: v0.1.21
changes:
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/58849
description: Message may now be a `printf`-like format string or function.
- version: v10.0.0
pr-url: https://github.com/nodejs/node/pull/18319
description: The `assert.ok()` (no arguments) will now use a predefined
error message.
-->
* `value` {any}
* `message` {string|Error|Function}
Tests if `value` is truthy. It is equivalent to
`assert.equal(!!value, true, message)`.
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 {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()`'``.
Be aware that in the `repl` the error message will be different to the one
thrown in a file! See below for further details.
```mjs
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)
```
```cjs
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)
```
```mjs
import assert from 'node:assert/strict';
// Using `assert()` works the same:
assert(0);
// AssertionError: The expression evaluated to a falsy value:
//
// assert(0)
```
```cjs
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])`
<!-- YAML
added: v10.0.0
-->
* `asyncFn` {Function|Promise}
* `error` {RegExp|Function|Object|Error}
* `message` {string}
* Returns: {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.
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.
Besides the async nature to await the completion behaves identically to
[`assert.throws()`][].
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.
If specified, `message` will be the message provided by the [`AssertionError`][]
if the `asyncFn` fails to reject.
```mjs
import assert from 'node:assert/strict';
await assert.rejects(
async () => {
throw new TypeError('Wrong value');
},
{
name: 'TypeError',
message: 'Wrong value',
},
);
```
```cjs
const assert = require('node:assert/strict');
(async () => {
await assert.rejects(
async () => {
throw new TypeError('Wrong value');
},
{
name: 'TypeError',
message: 'Wrong value',
},
);
})();
```
```mjs
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;
},
);
```
```cjs
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;
},
);
})();
```
```mjs
import assert from 'node:assert/strict';
assert.rejects(
Promise.reject(new Error('Wrong value')),
Error,
).then(() => {
// ...
});
```
```cjs
const assert = require('node:assert/strict');
assert.rejects(
Promise.reject(new Error('Wrong value')),
Error,
).then(() => {
// ...
});
```
`error` cannot be a string. If a string is provided as the second
argument, then `error` is assumed to be omitted and the string will be used for
`message` instead. This can lead to easy-to-miss mistakes. Please read the
example in [`assert.throws()`][] carefully if using a string as the second
argument gets considered.
## `assert.strictEqual(actual, expected[, message])`
<!-- YAML
added: v0.1.21
changes:
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/58849
description: Message may now be a `printf`-like format string or function.
- version: v10.0.0
pr-url: https://github.com/nodejs/node/pull/17003
description: Used comparison changed from Strict Equality to `Object.is()`.
-->
* `actual` {any}
* `expected` {any}
* `message` {string|Error|Function} Postfix `printf`-like arguments in case
it's used as format string.
If message is a function, it is called in case of a comparison failure. The
function receives the `actual` and `expected` arguments and has to return a
string that is going to be used as error message.
`printf`-like format strings and functions are beneficial for performance
reasons in case arguments are passed through. In addition, it allows nice
formatting with ease.
Tests strict equality between the `actual` and `expected` parameters as
determined by [`Object.is()`][].
```mjs
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(apples, oranges, 'apples %s !== oranges %s', apples, oranges);
// AssertionError [ERR_ASSERTION]: apples 1 !== oranges 2
assert.strictEqual(1, '1', new TypeError('Inputs are not identical'));
// TypeError: Inputs are not identical
assert.strictEqual(apples, oranges, (actual, expected) => {
// Do 'heavy' computations
return `I expected ${expected} but I got ${actual}`;
});
// AssertionError [ERR_ASSERTION]: I expected oranges but I got apples
```
```cjs
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(apples, oranges, 'apples %s !== oranges %s', apples, oranges);
// AssertionError [ERR_ASSERTION]: apples 1 !== oranges 2
assert.strictEqual(1, '1', new TypeError('Inputs are not identical'));
// TypeError: Inputs are not identical
assert.strictEqual(apples, oranges, (actual, expected) => {
// Do 'heavy' computations
return `I expected ${expected} but I got ${actual}`;
});
// AssertionError [ERR_ASSERTION]: I expected oranges but I got apples
```
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 {Error} then it will be thrown
instead of the [`AssertionError`][].
## `assert.throws(fn[, error][, message])`
<!-- YAML
added: v0.1.21
changes:
- version: v10.2.0
pr-url: https://github.com/nodejs/node/pull/20485
description: The `error` parameter can be an object containing regular
expressions now.
- version: v9.9.0
pr-url: https://github.com/nodejs/node/pull/17584
description: The `error` parameter can now be an object as well.
- version: v4.2.0
pr-url: https://github.com/nodejs/node/pull/3276
description: The `error` parameter can now be an arrow function.
-->
* `fn` {Function}
* `error` {RegExp|Function|Object|Error}
* `message` {string}
Expects the function `fn` to throw an error.
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.
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:
```mjs
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,
);
```
```cjs
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,
);
```
Validate instanceof using constructor:
```mjs
import assert from 'node:assert/strict';
assert.throws(
() => {
throw new Error('Wrong value');
},
Error,
);
```
```cjs
const assert = require('node:assert/strict');
assert.throws(
() => {
throw new Error('Wrong value');
},
Error,
);
```
Validate error message using {RegExp}:
Using a regular expression runs `.toString` on the error object, and will
therefore also include the error name.
```mjs
import assert from 'node:assert/strict';
assert.throws(
() => {
throw new Error('Wrong value');
},
/^Error: Wrong value$/,
);
```
```cjs
const assert = require('node:assert/strict');
assert.throws(
() => {
throw new Error('Wrong value');
},
/^Error: Wrong value$/,
);
```
Custom error validation:
The function must return `true` to indicate all internal validations passed.
It will otherwise fail with an [`AssertionError`][].
```mjs
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',
);
```
```cjs
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` cannot be a string. If a string is provided as the second
argument, then `error` is assumed to be omitted and the string will be used for
`message` instead. This can lead to easy-to-miss mistakes. Using the same
message as the thrown error message is going to result in an
`ERR_AMBIGUOUS_ARGUMENT` error. Please read the example below carefully if using
a string as the second argument gets considered:
```mjs
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]
```
```cjs
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.
## `assert.partialDeepStrictEqual(actual, expected[, message])`
<!-- YAML
added:
- v23.4.0
- v22.13.0
changes:
- version: v25.0.0
pr-url: https://github.com/nodejs/node/pull/59448
description: Promises are not considered equal anymore if they are not of
the same instance.
- version: v25.0.0
pr-url: https://github.com/nodejs/node/pull/57627
description: Invalid dates are now considered equal.
- version:
- v24.0.0
- v22.17.0
pr-url: https://github.com/nodejs/node/pull/57370
description: partialDeepStrictEqual is now Stable. Previously, it had been Experimental.
-->
* `actual` {any}
* `expected` {any}
* `message` {string|Error|Function}
Tests for partial 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. "Partial" equality means
that only properties that exist on the `expected` parameter are going to be
compared.
This method always passes the same test cases as [`assert.deepStrictEqual()`][],
behaving as a super set of it.
### Comparison details
* Primitive values are compared using [`Object.is()`][].
* [Type tags][Object.prototype.toString()] of objects should be the same.
* [`[[Prototype]]`][prototype-spec] of objects are not compared.
* Only [enumerable "own" properties][] are considered.
* {Error} names, messages, causes, and errors are always compared,
even if these are not enumerable properties.
`errors` is also compared.
* Enumerable own {Symbol} properties are compared as well.
* [Object wrappers][] are compared both as objects and unwrapped values.
* `Object` properties are compared unordered.
* {Map} keys and {Set} items are compared unordered.
* Recursion stops when both sides differ or both sides encounter a circular
reference.
* {WeakMap}, {WeakSet} and {Promise} instances are **not** compared
structurally. They are only equal if they reference the same object. Any
comparison between different `WeakMap`, `WeakSet`, or `Promise` instances
will result in inequality, even if they contain the same content.
* {RegExp} lastIndex, flags, and source are always compared, even if these
are not enumerable properties.
* Holes in sparse arrays are ignored.
```mjs
import assert from 'node:assert';
assert.partialDeepStrictEqual(
{ a: { b: { c: 1 } } },
{ a: { b: { c: 1 } } },
);
// OK
assert.partialDeepStrictEqual(
{ a: 1, b: 2, c: 3 },
{ b: 2 },
);
// OK
assert.partialDeepStrictEqual(
[1, 2, 3, 4, 5, 6, 7, 8, 9],
[4, 5, 8],
);
// OK
assert.partialDeepStrictEqual(
new Set([{ a: 1 }, { b: 1 }]),
new Set([{ a: 1 }]),
);
// OK
assert.partialDeepStrictEqual(
new Map([['key1', 'value1'], ['key2', 'value2']]),
new Map([['key2', 'value2']]),
);
// OK
assert.partialDeepStrictEqual(123n, 123n);
// OK
assert.partialDeepStrictEqual(
[1, 2, 3, 4, 5, 6, 7, 8, 9],
[5, 4, 8],
);
// AssertionError
assert.partialDeepStrictEqual(
{ a: 1 },
{ a: 1, b: 2 },
);
// AssertionError
assert.partialDeepStrictEqual(
{ a: { b: 2 } },
{ a: { b: '2' } },
);
// AssertionError
```
```cjs
const assert = require('node:assert');
assert.partialDeepStrictEqual(
{ a: { b: { c: 1 } } },
{ a: { b: { c: 1 } } },
);
// OK
assert.partialDeepStrictEqual(
{ a: 1, b: 2, c: 3 },
{ b: 2 },
);
// OK
assert.partialDeepStrictEqual(
[1, 2, 3, 4, 5, 6, 7, 8, 9],
[4, 5, 8],
);
// OK
assert.partialDeepStrictEqual(
new Set([{ a: 1 }, { b: 1 }]),
new Set([{ a: 1 }]),
);
// OK
assert.partialDeepStrictEqual(
new Map([['key1', 'value1'], ['key2', 'value2']]),
new Map([['key2', 'value2']]),
);
// OK
assert.partialDeepStrictEqual(123n, 123n);
// OK
assert.partialDeepStrictEqual(
[1, 2, 3, 4, 5, 6, 7, 8, 9],
[5, 4, 8],
);
// AssertionError
assert.partialDeepStrictEqual(
{ a: 1 },
{ a: 1, b: 2 },
);
// AssertionError
assert.partialDeepStrictEqual(
{ a: { b: 2 } },
{ a: { b: '2' } },
);
// AssertionError
```
[Object wrappers]: https://developer.mozilla.org/en-US/docs/Glossary/Primitive#Primitive_wrapper_objects_in_JavaScript
[Object.prototype.toString()]: https://tc39.github.io/ecma262/#sec-object.prototype.tostring
[`!=` operator]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Inequality
[`===` operator]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Strict_equality
[`==` operator]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Equality
[`AssertionError`]: #class-assertassertionerror
[`Class`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes
[`ERR_INVALID_RETURN_VALUE`]: errors.md#err_invalid_return_value
[`Object.is()`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is
[`assert.deepEqual()`]: #assertdeepequalactual-expected-message
[`assert.deepStrictEqual()`]: #assertdeepstrictequalactual-expected-message
[`assert.doesNotThrow()`]: #assertdoesnotthrowfn-error-message
[`assert.equal()`]: #assertequalactual-expected-message
[`assert.notDeepEqual()`]: #assertnotdeepequalactual-expected-message
[`assert.notDeepStrictEqual()`]: #assertnotdeepstrictequalactual-expected-message
[`assert.notEqual()`]: #assertnotequalactual-expected-message
[`assert.notStrictEqual()`]: #assertnotstrictequalactual-expected-message
[`assert.ok()`]: #assertokvalue-message
[`assert.strictEqual()`]: #assertstrictequalactual-expected-message
[`assert.throws()`]: #assertthrowsfn-error-message
[`getColorDepth()`]: tty.md#writestreamgetcolordepthenv
[`util.format()`]: util.md#utilformatformat-args
[enumerable "own" properties]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Enumerability_and_ownership_of_properties
[prototype-spec]: https://tc39.github.io/ecma262/#sec-ordinary-object-internal-methods-and-internal-slots