assert.strictEqual()
Compares two values with Object.is() and throws an AssertionError when they differ.
assert.strictEqual(actual, expected[, message])- Added in Node.js v0.1.21
Parameters
| Parameter | Type | Description |
|---|---|---|
$actual | any | The value produced by the code under test. |
$expected | any | The value it is compared against, using Object.is(). |
$messageoptional | string | Error | Function | Error message, an Error instance to throw instead, or a function called on comparison failure. |
Errors
Throws an AssertionError with code ERR_ASSERTION when Object.is(actual, expected) is false; if message is an Error instance, that error is thrown instead.
Changelog
- PHP v26.0.0Message may now be a printf-like format string or function.
- PHP v10.0.0The comparison used changed from strict equality (===) to Object.is().
assert.strictEqual() is the default choice for comparing two primitives. It does no coercion at all, so '8080' never equals 8080, and it prints both sides with a diff when it fails — the reason to prefer it over assert.ok(a === b), which can only report false.
Object.is(), not ===
Since Node 10 the comparison is Object.is(), which differs from === in exactly two places:
assert.strictEqual(NaN, NaN)passes. Under===it would fail.assert.strictEqual(0, -0)fails. Under===it would pass.
The -0 case bites people testing rounding, Math.round(), and anything that multiplies by a negative zero. If you do not care about the sign of zero, compare value + 0 or assert on Object.is(value, 0) || Object.is(value, -0).
Objects are compared by reference
Two structurally identical objects are different values, so strictEqual({a: 1}, {a: 1}) throws. That is often what you want when checking that a cache returned the same instance; for structural comparison use assert.deepStrictEqual().
Example
When to use it
- Check that a function returned the exact number, string or boolean you expected
- Assert that a memoising factory handed back the very same object instance on the second call
- Verify an error's code property is exactly 'ENOENT' rather than merely error-ish
Frequently asked questions
Why does assert.strictEqual(0, -0) fail?
Because since Node 10 the comparison is Object.is(), not ===, and Object.is distinguishes +0 from -0. Math.round, multiplication by a negative, and parseFloat('-0') can all produce -0 where you expected 0.
What is the difference between assert.equal() and assert.strictEqual()?
assert.equal() uses loose == comparison and is classified as Legacy; assert.strictEqual() uses Object.is() and does no type coercion. strictEqual catches a value silently changing from the number 200 to the string '200', which equal() lets through.
Can assert.strictEqual() compare objects or arrays?
Only by reference — two distinct objects with identical contents will throw. Use assert.deepStrictEqual() to compare structure recursively.
More examples
Reference identity versus structure
The first assertion proves the memoiser is actually caching rather than rebuilding an equal object. The second shows the flip side: strictEqual can never confirm structure, so a test that only cares about shape must use deepStrictEqual instead.
const assert = require('node:assert');
function memoize(fn) {
const cache = new Map();
return (key) => {
if (!cache.has(key)) cache.set(key, fn(key));
return cache.get(key);
};
}
const load = memoize((id) => ({ id }));
const first = load(1);
const second = load(1);
// strictEqual is the right tool: we want the SAME object back.
assert.strictEqual(first, second);
console.log('cache returned the same instance');
// A fresh object with identical contents is a different value.
try {
assert.strictEqual(first, { id: 1 });
} catch (err) {
console.log('structurally equal but not identical ->', err.code);
}Inside the built-in test runner
The commented failure is the one to memorise: Math.round(-0.4) is -0, so a clamp implemented with Math.round alone can hand back -0 and fail an assertion that looks obviously correct. The diff makes the sign visible, which a console.log of the value would not.
const test = require('node:test');
const assert = require('node:assert/strict');
function clampPercent(n) {
return Math.min(100, Math.max(0, Math.round(n)));
}
test('clampPercent', () => {
assert.strictEqual(clampPercent(42.4), 42);
assert.strictEqual(clampPercent(150), 100);
assert.strictEqual(clampPercent(-3), 0);
});
// $ node --test
// If clampPercent(-3) ever returned -0 instead of 0, the runner prints:
// AssertionError [ERR_ASSERTION]: Expected values to be strictly equal:
// + actual - expected
// + -0
// - 0A message function, evaluated only on failure
Passing a function defers building the message until an assertion actually fails, so a passing test never pays for the serialisation. This form was added in Node 26; on earlier versions the function is stringified into the message instead, so guard it if you support older runtimes.
const assert = require('node:assert');
function expensiveContext(rows) {
// Imagine this serialises a large object.
return `dump: ${JSON.stringify(rows)}`;
}
const rows = [{ id: 1 }, { id: 2 }];
// Node 26+: message may be a function, called only when the comparison fails.
try {
assert.strictEqual(rows.length, 3, () => expensiveContext(rows));
} catch (err) {
console.log(err.message);
// dump: [{"id":1},{"id":2}]
}
Discussion