In software development, assertions state facts about values or pieces of code that must be true. If they aren’t, an exception is thrown. Node.js supports assertions via its built-in module assert
– for example:
import assert from 'node:assert/strict';
assert.equal(3 + 5, 8);
This assertion states that the expected result of 3 plus 5 is 8. The import statement uses the recommended strict
version of assert
.
In this book, assertions are used in two ways: to document results in code examples and to implement test-driven exercises.
In code examples, assertions express expected results. Take, for example, the following function:
function id(x) {
return x;
}
id()
returns its parameter. We can show it in action via an assertion:
assert.equal(id('abc'), 'abc');
In the examples, I usually omit the statement for importing assert
.
The motivation behind using assertions is:
The exercises for this book are test-driven, via the test framework Mocha. Checks inside the tests are made via methods of assert
.
The following is an example of such a test:
// For the exercise, we must implement the function hello().
// The test checks if we have done it properly.
test('First exercise', () => {
assert.equal(hello('world'), 'Hello world!');
assert.equal(hello('Jane'), 'Hello Jane!');
assert.equal(hello('John'), 'Hello John!');
assert.equal(hello(''), 'Hello !');
});
For more information, see “Getting started with exercises” (§12).
The strict equal()
uses ===
to compare values. Therefore, an object is only equal to itself – even if another object has the same content (because ===
does not compare the contents of objects, only their identities):
assert.notEqual({foo: 1}, {foo: 1});
deepEqual()
is a better choice for comparing objects:
assert.deepEqual({foo: 1}, {foo: 1});
This method works for Arrays, too:
assert.notEqual(['a', 'b', 'c'], ['a', 'b', 'c']);
assert.deepEqual(['a', 'b', 'c'], ['a', 'b', 'c']);
assert
For the full documentation, see the Node.js docs.
assert.equal()
assert.equal(actual, expected, message?)
actual === expected
must be true
. If not, an AssertionError
is thrown.
assert.equal(3+3, 6);
assert.notEqual(actual, expected, message?)
actual !== expected
must be true
. If not, an AssertionError
is thrown.
assert.notEqual(3+3, 22);
The optional last parameter message
can be used to explain what is asserted. If the assertion fails, the message is used to set up the AssertionError
that is thrown.
let e;
try {
const x = 3;
assert.equal(x, 8, 'x must be equal to 8')
} catch (err) {
assert.equal(
String(err),
'AssertionError [ERR_ASSERTION]: x must be equal to 8');
}
assert.deepEqual()
assert.deepEqual(actual, expected, message?)
actual
must be deeply equal to expected
. If not, an AssertionError
is thrown.
assert.deepEqual([1,2,3], [1,2,3]);
assert.deepEqual([], []);
// To .equal(), an object is only equal to itself:
assert.notEqual([], []);
assert.notDeepEqual(actual, expected, message?)
actual
must not be deeply equal to expected
. If it is, an AssertionError
is thrown.
assert.notDeepEqual([1,2,3], [1,2]);
assert.throws()
If we want to (or expect to) receive an exception, we need assert.throws()
: This function calls its first parameter, the function callback
, and only succeeds if it throws an exception. Additional parameters can be used to specify what that exception must look like.
assert.throws(callback, message?): void
assert.throws(
() => {
null.prop;
}
);
assert.throws(callback, errorClass, message?): void
assert.throws(
() => {
null.prop;
},
TypeError
);
assert.throws(callback, errorRegExp, message?): void
assert.throws(
() => {
null.prop;
},
/^TypeError: Cannot read properties of null \(reading 'prop'\)$/
);
assert.throws(callback, errorObject, message?): void
assert.throws(
() => {
null.prop;
},
{
name: 'TypeError',
message: "Cannot read properties of null (reading 'prop')",
}
);
assert.fail()
assert.fail(messageOrError?)
By default, it throws an AssertionError
when it is called. That is occasionally useful for unit testing. messageOrError
can be:
Error
(or a subclass). That enables us to throw a different value.
try {
functionThatShouldThrow();
assert.fail();
} catch (_) {
// Success
}