Node.js Assert Module
What is the Assert Module?
The Assert module provides a simple yet powerful set of assertion tests for validating invariants in your code.
It's a core Node.js module that doesn't require installation.
Key features include:
- Simple truthy/falsy assertions
- Strict and loose equality checks
- Deep object comparison
- Error throwing and handling
- Support for async/await patterns
Note: While not as feature-rich as testing frameworks like Jest or Mocha, the Assert module is lightweight and perfect for simple testing needs or when you want to avoid external dependencies.
Getting Started with Assert
Here's a quick example of using the Assert module to test a simple function:
Basic Assertion Example
const assert = require('assert').strict;
// Function to test
function add(a, b) {
if (typeof a !== 'number' || typeof b !== 'number') {
throw new TypeError('Inputs must be numbers');
}
return a + b;
}
// Test cases
assert.strictEqual(add(2, 3), 5, '2 + 3 should equal 5');
// Test error case
assert.throws(
() => add('2', 3),
TypeError,
'Should throw TypeError for non-number input'
);
console.log('All tests passed!');
Run example »
Importing and Setup
There are several ways to import and use the Assert module in your Node.js application:
CommonJS Import (Node.js)
// Basic require
const assert = require('assert');
// Using strict mode (recommended)
const assert = require('assert').strict;
// Destructuring specific methods
const { strictEqual, deepStrictEqual, throws } = require('assert');
// For async/await tests
const { rejects, doesNotReject } = require('assert').strict;
ES Modules (Node.js 12+)
// Using default import
import assert from 'assert';
// Using strict mode with ESM
import { strict as assert } from 'assert';
// Importing specific methods
import { strictEqual, deepStrictEqual } from 'assert';
// Dynamic import
const { strict: assert } = await import('assert');
Best Practice: The strict mode is recommended as it provides more accurate comparisons and better error messages.
It's also more aligned with future versions of Node.js where strict mode will be the default.
Core Assertion Methods
The Assert module provides several methods for making assertions about values in your code.
These methods form the foundation of testing with the Assert module.
assert(value[, message])
Tests if a value is truthy. If the value is falsy, an AssertionError is thrown.
const assert = require('assert');
// This will pass
assert(true);
assert(1);
assert('string');
assert({});
try {
// This will throw an AssertionError
assert(false, 'This value is not truthy');
} catch (err) {
console.error(`Error: ${err.message}`);
}
try {
// These will also throw errors
assert(0);
assert('');
assert(null);
assert(undefined);
} catch (err) {
console.error(`Error: ${err.message}`);
}
Run example »
assert.ok(value[, message])
This is an alias for assert()
.
const assert = require('assert');
// These assertions are equivalent
assert.ok(true, 'This value is truthy');
assert(true, 'This value is truthy');
Value Comparison
The Assert module provides multiple ways to compare values, each with different behaviors regarding type coercion and object comparison.
assert.equal(actual, expected[, message])
Tests shallow, coercive equality between the actual and expected parameters using the equality operator (==
).
const assert = require('assert');
// These will pass (coercive equality)
assert.equal(1, 1);
assert.equal('1', 1); // String is coerced to number
assert.equal(true, 1); // Boolean is coerced to number
try {
// This will throw an error
assert.equal(1, 2, '1 is not equal to 2');
} catch (err) {
console.error(`Error: ${err.message}`);
}
Run example »
assert.strictEqual(actual, expected[, message])
Tests strict equality between the actual and expected parameters using the strict equality operator (===
).
const assert = require('assert');
// This will pass
assert.strictEqual(1, 1);
try {
// These will throw errors (strict equality)
assert.strictEqual('1', 1, 'String "1" is not strictly equal to number 1');
assert.strictEqual(true, 1, 'true is not strictly equal to 1');
} catch (err) {
console.error(`Error: ${err.message}`);
}
Run example »
Best Practice: It's recommended to use strictEqual()
over equal()
to avoid unexpected type coercion issues.
Object and Array Comparison
When working with objects and arrays, you'll need to use deep equality checks to compare their contents rather than just their references.
For comparing objects and arrays, Node.js provides deep equality functions:
assert.deepEqual(actual, expected[, message])
Tests for deep equality between the actual and expected parameters with loose equality (==
).
assert.deepStrictEqual(actual, expected[, message])
Tests for deep equality between the actual and expected parameters with strict equality (===
).
const assert = require('assert');
// Objects with the same structure
const obj1 = { a: 1, b: { c: 2 } };
const obj2 = { a: 1, b: { c: 2 } };
const obj3 = { a: '1', b: { c: '2' } };
// These will pass
assert.deepEqual(obj1, obj2);
assert.deepStrictEqual(obj1, obj2);
// This will pass (loose equality)
assert.deepEqual(obj1, obj3);
try {
// This will throw an error (strict equality)
assert.deepStrictEqual(obj1, obj3, 'Objects are not strictly deep-equal');
} catch (err) {
console.error(`Error: ${err.message}`);
}
// Arrays
const arr1 = [1, 2, [3, 4]];
const arr2 = [1, 2, [3, 4]];
const arr3 = ['1', '2', ['3', '4']];
// These will pass
assert.deepEqual(arr1, arr2);
assert.deepStrictEqual(arr1, arr2);
// This will pass (loose equality)
assert.deepEqual(arr1, arr3);
try {
// This will throw an error (strict equality)
assert.deepStrictEqual(arr1, arr3, 'Arrays are not strictly deep-equal');
} catch (err) {
console.error(`Error: ${err.message}`);
}
Run example »
Inequality and Negation
Just as important as checking for equality is verifying that values are not equal when they shouldn't be.
assert.notEqual(actual, expected[, message])
Tests shallow, coercive inequality using the inequality operator (!=
).
assert.notStrictEqual(actual, expected[, message])
Tests strict inequality using the strict inequality operator (!==
).
const assert = require('assert');
// These will pass
assert.notEqual(1, 2);
assert.notStrictEqual('1', 1);
try {
// This will throw an error
assert.notEqual(1, '1', '1 is coercively equal to "1"');
} catch (err) {
console.error(`Error: ${err.message}`);
}
try {
// This will throw an error
assert.notStrictEqual(1, 1, '1 is strictly equal to 1');
} catch (err) {
console.error(`Error: ${err.message}`);
}
Run example »
Deep Inequality
assert.notDeepEqual(actual, expected[, message])
Tests for deep inequality with loose inequality.
assert.notDeepStrictEqual(actual, expected[, message])
Tests for deep inequality with strict inequality.
const assert = require('assert');
const obj1 = { a: 1, b: 2 };
const obj2 = { a: 1, b: 3 };
const obj3 = { a: '1', b: '2' };
// These will pass
assert.notDeepEqual(obj1, obj2);
assert.notDeepStrictEqual(obj1, obj2);
assert.notDeepStrictEqual(obj1, obj3);
try {
// This will throw an error (loose equality)
assert.notDeepEqual(obj1, obj3, 'obj1 is loosely deep-equal to obj3');
} catch (err) {
console.error(`Error: ${err.message}`);
}
Run example »
Error Handling
Testing that your code throws the expected errors is a critical part of writing robust applications.
The Assert module provides several methods for this purpose.
assert.throws(fn[, error][, message])
Expects the function fn
to throw an error. If not, an AssertionError is thrown.
const assert = require('assert');
// Function that throws an error
function throwingFunction() {
throw new Error('Error thrown');
}
// This will pass
assert.throws(throwingFunction);
// Check for a specific error message
assert.throws(
throwingFunction,
/Error thrown/,
'Unexpected error message'
);
// Check for a specific error type
assert.throws(
throwingFunction,
Error,
'Wrong error type'
);
// Check with a validation function
assert.throws(
throwingFunction,
function(err) {
return err instanceof Error && /thrown/.test(err.message);
},
'Error validation failed'
);
try {
// This will throw an AssertionError
assert.throws(() => {
// This function doesn't throw
return 'no error';
}, 'Expected function to throw');
} catch (err) {
console.error(`Error: ${err.message}`);
}
Run example »
assert.doesNotThrow(fn[, error][, message])
Expects the function fn
to not throw an error. If it does, the error is propagated.
const assert = require('assert');
// This will pass
assert.doesNotThrow(() => {
return 'no error';
});
try {
// This will throw the original error
assert.doesNotThrow(() => {
throw new Error('This will be thrown');
}, 'Unexpected error');
} catch (err) {
console.error(`Error: ${err.message}`);
}
Run example »
Testing Asynchronous Code
Modern JavaScript makes heavy use of asynchronous patterns.
The Assert module provides utilities for testing both Promise-based and callback-based asynchronous code.
assert.rejects(asyncFn[, error][, message])
Awaits the asyncFn
promise or async function and expects it to reject.
const assert = require('assert');
async function asyncTest() {
// Function that returns a rejecting promise
function failingAsyncFunction() {
return Promise.reject(new Error('Async error'));
}
// This will pass
await assert.rejects(
failingAsyncFunction(),
/Async error/
);
// This will also pass
await assert.rejects(
async () => {
throw new Error('Async function error');
},
{
name: 'Error',
message: 'Async function error'
}
);
try {
// This will throw an AssertionError
await assert.rejects(
Promise.resolve('success'),
'Expected promise to reject'
);
} catch (err) {
console.error(`Error: ${err.message}`);
}
}
// Run the async test
asyncTest().catch(err => console.error(`Unhandled error: ${err.message}`));
Run example »
assert.doesNotReject(asyncFn[, error][, message])
Awaits the asyncFn
promise or async function and expects it to fulfill.
const assert = require('assert');
async function asyncTest() {
// This will pass
await assert.doesNotReject(
Promise.resolve('success')
);
// This will also pass
await assert.doesNotReject(
async () => {
return 'async function success';
}
);
try {
// This will throw the original rejection reason
await assert.doesNotReject(
Promise.reject(new Error('Failure')),
'Expected promise to fulfill'
);
} catch (err) {
console.error(`Error: ${err.message}`);
}
}
// Run the async test
asyncTest().catch(err => console.error(`Unhandled error: ${err.message}`));
Run example »
Other Assertion Methods
assert.match(string, regexp[, message])
Expects the string input to match the regular expression.
const assert = require('assert');
// This will pass
assert.match('I love Node.js', /Node\.js/);
try {
// This will throw an AssertionError
assert.match('Hello World', /Node\.js/, 'String does not match the pattern');
} catch (err) {
console.error(`Error: ${err.message}`);
}
Run example »
assert.fail([message])
Throws an AssertionError with the provided message or a default message.
const assert = require('assert');
try {
// This always throws an AssertionError
assert.fail('This test always fails');
} catch (err) {
console.error(`Error: ${err.message}`);
}
Run example »
Strict Mode
Node.js provides a strict mode for assertions which uses strict equality for all comparisons.
It's recommended to use strict mode for more predictable results.
// Import the strict version of assert
const assert = require('assert').strict;
// These are equivalent
assert.strictEqual(1, 1);
assert.equal(1, 1); // In strict mode, this is the same as strictEqual
// These are equivalent
assert.deepStrictEqual({ a: 1 }, { a: 1 });
assert.deepEqual({ a: 1 }, { a: 1 }); // In strict mode, this is the same as deepStrictEqual
try {
// This will throw an error in strict mode
assert.equal('1', 1);
} catch (err) {
console.error(`Error: ${err.message}`);
}
Run example »
When to Use Node.js Assert vs Testing Frameworks
Use Node.js Assert When:
- Writing simple scripts or small utilities
- Creating quick tests during development
- You want to avoid external dependencies
- Building internal Node.js modules
Use a Testing Framework (Jest, Mocha, etc.) When:
- Working on larger projects
- You need features like test runners, reporters, and mocking
- Building applications that require comprehensive test coverage
- You need better error reporting and test organization
For serious application testing, consider using the built-in Node.js Test Runner introduced in Node.js v18 or a dedicated testing framework like Jest, Mocha, or AVA.