Skip to main content
The node:assert module provides a set of assertion functions for verifying invariants in your code. It’s primarily used for testing but can also be used for runtime validation.

Installation

// Strict mode (recommended)
import assert from 'node:assert/strict';
// or
const assert = require('node:assert/strict');

// Legacy mode
import assert from 'node:assert';
// or
const assert = require('node:assert');

Strict vs Legacy Mode

Strict mode (recommended) uses strict equality (===) and is more predictable:
import assert from 'node:assert/strict';

assert.equal(1, 1); // OK
assert.equal(1, '1'); // AssertionError: 1 === '1'
Legacy mode uses loose equality (==) and may have surprising results:
import assert from 'node:assert';

assert.equal(1, '1'); // OK (loose equality)

Basic Assertions

assert(value[, message])

Alias for assert.ok(). Tests if value is truthy.
import assert from 'node:assert/strict';

assert(true); // OK
assert(1); // OK
assert(false); // AssertionError
assert(0); // AssertionError

assert.ok(value[, message])

Tests if value is truthy.
assert.ok(true); // OK
assert.ok('non-empty string'); // OK
assert.ok(0); // AssertionError

assert.fail([message])

Throws an AssertionError immediately.
assert.fail('Operation failed');
// AssertionError: Operation failed

Equality Assertions

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

Tests shallow, coercive equality with == (legacy) or === (strict).
assert.equal(1, 1); // OK
assert.equal('hello', 'hello'); // OK

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

Tests shallow, coercive inequality.
assert.notEqual(1, 2); // OK
assert.notEqual('a', 'b'); // OK

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

Tests strict equality using ===.
assert.strictEqual(1, 1); // OK
assert.strictEqual(1, '1'); // AssertionError

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

Tests strict inequality using !==.
assert.notStrictEqual(1, 2); // OK
assert.notStrictEqual(1, '1'); // OK

Deep Equality Assertions

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

Tests deep equality between objects, arrays, and primitives.
import assert from 'node:assert/strict';

assert.deepEqual({ a: 1 }, { a: 1 }); // OK
assert.deepEqual([1, 2, 3], [1, 2, 3]); // OK
assert.deepEqual({ a: { b: 1 } }, { a: { b: 1 } }); // OK

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

Tests deep inequality.
assert.notDeepEqual({ a: 1 }, { a: 2 }); // OK
assert.notDeepEqual([1, 2], [1, 3]); // OK

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

Tests deep strict equality (recommended for objects).
assert.deepStrictEqual({ a: 1 }, { a: 1 }); // OK
assert.deepStrictEqual({ a: 1 }, { a: '1' }); // AssertionError
assert.deepStrictEqual([1, 2], [1, 2]); // OK

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

Tests deep strict inequality.
assert.notDeepStrictEqual({ a: 1 }, { a: 2 }); // OK
assert.notDeepStrictEqual({ a: 1 }, { b: 1 }); // OK

Error Assertions

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

Expects the function to throw an error.
assert.throws(
  () => {
    throw new Error('Wrong value');
  },
  Error
); // OK

// With error message validation
assert.throws(
  () => {
    throw new Error('Wrong value');
  },
  /Wrong/
); // OK

// With custom validation
assert.throws(
  () => {
    throw new Error('Wrong value');
  },
  (err) => {
    return err instanceof Error && err.message === 'Wrong value';
  }
); // OK

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

Expects the function not to throw an error.
assert.doesNotThrow(() => {
  return 42;
}); // OK

assert.doesNotThrow(() => {
  throw new Error('Oops');
}); // AssertionError

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

Expects a promise or async function to reject.
await assert.rejects(
  async () => {
    throw new Error('Async error');
  },
  Error
); // OK

await assert.rejects(
  Promise.reject(new Error('Failed')),
  /Failed/
); // OK

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

Expects a promise or async function not to reject.
await assert.doesNotReject(
  async () => {
    return 42;
  }
); // OK

await assert.doesNotReject(
  Promise.resolve('success')
); // OK

Pattern Matching

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

Tests if string matches the regular expression.
assert.match('hello world', /world/); // OK
assert.match('hello world', /^hello/); // OK
assert.match('hello world', /goodbye/); // AssertionError

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

Tests if string does not match the regular expression.
assert.doesNotMatch('hello world', /goodbye/); // OK
assert.doesNotMatch('hello world', /world/); // AssertionError

Custom Assertions

assert.ifError(value)

Throws value if it’s not null or undefined. Useful for testing error-first callbacks.
function callback(err, data) {
  assert.ifError(err); // Throws if err is not null/undefined
  console.log(data);
}

Error Messages

All assertion methods accept an optional message parameter:
assert.strictEqual(actual, expected, 'Values should match');

// With template literals
assert.strictEqual(
  actual,
  expected,
  `Expected ${expected} but got ${actual}`
);

Common Testing Patterns

Testing Object Properties

import assert from 'node:assert/strict';

const user = {
  name: 'John',
  age: 30,
  email: '[email protected]'
};

assert.strictEqual(user.name, 'John');
assert.strictEqual(user.age, 30);
assert.ok(user.email.includes('@'));

Testing Arrays

const numbers = [1, 2, 3, 4, 5];

assert.strictEqual(numbers.length, 5);
assert.deepStrictEqual(numbers, [1, 2, 3, 4, 5]);
assert.ok(numbers.includes(3));

Testing Async Functions

import assert from 'node:assert/strict';

async function fetchData() {
  // Simulated async operation
  return { status: 'success' };
}

// In a test
const result = await fetchData();
assert.strictEqual(result.status, 'success');

Testing Error Conditions

function divide(a, b) {
  if (b === 0) {
    throw new Error('Division by zero');
  }
  return a / b;
}

// Test error case
assert.throws(
  () => divide(10, 0),
  /Division by zero/
);

// Test success case
assert.doesNotThrow(() => divide(10, 2));
assert.strictEqual(divide(10, 2), 5);

Validation Functions

function validateEmail(email) {
  assert.ok(email, 'Email is required');
  assert.match(email, /@/, 'Email must contain @');
  assert.match(email, /\./, 'Email must contain domain');
}

validateEmail('[email protected]'); // OK

AssertionError Class

All assertion failures throw an AssertionError:
try {
  assert.strictEqual(1, 2);
} catch (err) {
  console.log(err instanceof assert.AssertionError); // true
  console.log(err.actual); // 1
  console.log(err.expected); // 2
  console.log(err.operator); // 'strictEqual'
}

Best Practices

  1. Use strict mode - More predictable and catches more bugs
  2. Use descriptive messages - Make failures easier to debug
  3. Use deepStrictEqual for objects - More reliable than deepEqual
  4. Test both success and failure cases - Ensure error handling works
  5. Use async assertions for promises - Properly handle async errors
  • util - Utility functions
  • Test runners: Mocha, Jest, Vitest, Node.js built-in test runner