The assert module in Node.js is used to test expressions for the functionalities in Node.js applications. If the result of the test returns false, assert throws an error and stops the program. You can use assert modules with unit test tools like unit Js, Mocha, and Chai.
Developers use assert to test for invariants in their applications. But what are invariants and what are the different methods to verify them?
Invariants are expressions or conditions that need to return true at some point in a program. Let’s look closely at the expression below:
let a = 5; let b = 3; let correct = (a > b); console.log (correct);
This should return “true” when you run it on your terminal or Bash. What if, for some reason, the application above returns false and there are some other expressions depending on it?
If we change the greater than sign >
to <
and run this code, we should get “false.” Let’s imagine that the change in sign above is a mistake and the program returns an unexpected result because of this mistake. How would the development team trace this mistake and ensure re-occurrence does not happen?
The expression above is an example of an invariant. To guarantee that the code returns “true” as expected, Node.js development teams use the assert module to test expressions.
There are different assert methods—which one you use boils down to what you are testing invariants for in your Node.js application. To use this Node.js module, install it by running the command below:
npm i assert
Let’s dive into the different assert methods and examples of where we can use them in our application.
Assert(value[, message])
methodThis method is used for verifying if the value of an invariant is true. It’s an alias of assert.ok(value[, message])
and can be used in the same way.
//import assert module var assert = require('assert'); //declare variables var a = 5; var b = 3; //This code below would throw an assert error and end program assert(a < b); /**This is an expample to show how to use assert.ok(). Comment assert() out, run this code to get the same response. assert.ok(a < b); **/
The program above is an example of how to use the assert()
method in an application. If you look closely, you’ll see that the expression is the same as the first expression used to explain invariants.
Note: No assert methods will throw an exception if the invariant expression returns true. They will only throw an error if invariants return false or 0.
Assert.deepStrictEqual (actual, expected[, message])
methodThis method uses assert in strict mode, so you’ll use this method when checking for equality instead of the assert.deepEqual
method. This is because assert.deepEqual
uses abstract equality comparison; therefore, it can produce surprising results.
An example of how to use Assert.deepStrictEqual()
method is illustrated in the expression below:
//This is how to import the assert module in strict mode const assert = require('assert').strict; // This fails because 1 !== '1 for strict equality comparison. assert.deepStrictEqual({ a: 1 }, { a: '1' }); /**Where { a: 1 } = actual value and { a: '1' } = expected value. AssertionError: Expected inputs to be strictly deep-equal: **/
Assert.fail([message])
methodImagine you need to add a custom message to your invariant test when your assert returns false. This is a simple type of debugging method. For instance, developers will embed the following into their codes so they know what the error is:
console.log('When you get here, log this so i know my error')
You can insert a custom error message with the expression below:
//Import assert module const assert = require('assert').strict; /** AssertionError [ERR_ASSERTION]: Failed. This just prints failed as error message. This is not a good practice**/ assert.fail(); // AssertionError [ERR_ASSERTION]: This is why I failed assert.fail('This is why I failed'); // TypeError: This is why I failed assert.fail(new TypeError('This is why I failed'));
Assert.ifError(value)
methodPicture this: you just got an error, you probably know what line the error is coming from, but you don’t just understand why the program is throwing an error.
With the Assert.ifError
method, you can test error callback arguments to understand where exactly the error is coming from. A quick example of using this method is illustrated in the expression below:
//This method is used in strict mode const assert = require('assert').strict; //Define error callback arguement let err; (function error1() { err = new Error('test error'); })(); //create an ifError function (function ifError1() { //return this error if program resolves into an error assert.ifError(err); })(); /**AssertionError [ERR_ASSERTION]: ifError got unwanted exception: test error at ifError1 at error1 **/
Assert.doesNotMatch(string, regexp[, message])
methodThis method is used to verify that the actual input string does not match the expected expression. The assert.doesNotMatch()
method added in Node.js version v13.6.0, v12.16.0 is experimental and may be completely removed. This method currently uses assert in strict mode.
The simple expression below shows how to use the assert.doesNotMatch()
method to verify invariants.
//import assert using strict mode const assert = require('assert').strict; assert.doesNotMatch('I will fail', /fail/); /** AssertionError [ERR_ASSERTION]: The input was expected to not match because fail is contained in the actual and expected string ...**/ assert.doesNotMatch(123, /pass/); /**AssertionError [ERR_ASSERTION]: The "string" argument must be of type string.**/ assert.doesNotMatch('I will pass', /different/); /** This passes the test with no error since actual and expeted string have no word alike **/
Assert.doesNotReject(asyncFn\[, error\][, message])
methodThis method is used to check that promise is not rejected in an asynchronous function. If the expression does not return a promise, Assert.doesNotReject()
returns a rejected promise.
Using this method is not very useful because catching a rejection just to reject it again is not beneficial. The best thing to do is to add comments next to the specific code path that should not reject and keep error messages as expressive as possible.
An example on how to use this method is shown in the expression below:
(async () => { await assert.doesNotReject( async () => { throw new TypeError('Wrong value'); }, SyntaxError ); })(); assert.doesNotReject(Promise.reject(new TypeError('Wrong value'))) .then(() => { // ... });
What if you want to check if promise in an invariant was rejected?
The assert method to use in this scenario is Assert.rejects()
method. This method awaits the returned promise in an asynchronous function to verify that promise is rejected.
If the promise is not rejected, it throws an error. The expression below shows simple ways we can use this method.
(async () => { await assert.rejects( async () => { throw new TypeError('Wrong value'); }, { name: 'TypeError', message: 'Wrong value' } ); })(); assert.rejects( Promise.reject(new Error('Wrong value')), Error ).then(() => { // ... });
Assert in strict mode involves using strict equality comparison method to verify invariants. In assert strict mode, non-strict methods behave as their relative strict methods.
For example, assert.deepEqual()
will behave like assert.deepStrictEqual()
, while assert.notEqual()
will behave like assert.notStrictEqual()
.
To use assert in strict mode, import the assert module into your application using any of these methods:
//import the assert module using strict mode const assert = require('assert').strict; //import the assert module using strict mode const assert = require('assert/strict');
In legacy mode, comparison of invariants involve the use of abstract equality comparison. It is advised to always use the strict mode to compare actual and expected values of invariants.
To import the assert module into your application using legacy mode, use the expression below:
const assert = require('assert');
Here are the different assert comparison methods in legacy mode.
Assert.deepEqual(actual, expected[, message])
methodThe assert deep equality method uses the abstract equality comparison. It is used to check for equality between actual and expected results. With this method, child properties are also tested. A quick example of how to use the assert.deepEqual()
method is shown in the expression below:
const assert = require('assert'); const val1 = { x: { y: 1 } }; const val2 = { x: { y: 2 } }; const val3 = { x: { y: 1 } }; assert.deepEqual(val1, val3); // Returns OK since val1 is equal to val3 // Values of b are different (Child properties) assert.deepEqual(val1, val2); // AssertionError: { a: { b: 1 } } deepEqual { a: { b: 2 } }
What if rather for equality, you want to test for deep inequality? The assert method to use in this case is the assert.notDeepEqual(actual, expected[, message])
. This method is used for testing deep inequality and would throw an exception if the actual and expected value are equal.
An example of how to use this method is shown below:
const assert = require('assert'); const val1 = { x: { y: 1 } }; const val2 = { x: { y: 2 } }; const val3 = { x: { y: 1 } }; assert.notDeepEqual(val1, val3); // AssertionError: { x: { y: 1 } } notDeepEqual { x: { y: 2 } } /** Values of b are different (Child properties)**/ assert.notDeepEqual(val1, val2); // Ok because val1 and val2 are not equal
Note: This method is depreciated because of its instability, so it is advised to use assert in strict mode, i.e., the Asset.deepStrictEqual
and Asset.notDeepStrictEqual
methods.
Assert.equal(actual, expected[, message])
methodThis method is used to test shallow comparison between the actual and expected result using abstract equality comparison. It’s hardly used to test child value as it is meant for shallow tests, and it’s also advised to use the Assert.deepStrictEqual()
method instead of this method. An example of how to use Assert.equal()
is shown in the expression below:
//Import the assert module const assert = require('assert'); assert.equal(1, 1); // This throws no exception since 1 == 1 assert.equal(1, '1'); /** This throws no exception since with abstract equality comparison 1 == '1' **/ assert.equal(NaN, NaN); // This throws no exception assert.equal(1, 2); // This throws an error, AssertionError: 1 == 2 assert.equal({ a: { x: 1 } }, { a: { x: 1 } }); /**This throws an error AssertionError: { a: { x: 1 } } == { a: { x: 1 } } because it dosen't check child value**/
The assert.notEqual()
method is used to check for shallow inequality, just as assert.equal()
is used to check for equality.
Assert.notEqual(actual, expected[, message])
methodJust like the assert.equal method is used for shallow equality comparison, this method is used for shallow inequality comparison.
You should not use this method for testing child value as it is meant for shallow tests.
Also, this is a legacy mode invariant method and legacy mode invariant methods are for abstract comparison. For strict comparison and also, to test for child value, use the assert.notStrictEqual
method.
//Import the assert module const assert = require('assert'); assert.notEqual(1, 1); // This throws an exception since 1 == 1 assert.notEqual(1, '1'); /** This throws an exception since with abstract equality comparison 1 == '1' **/ assert.notEqual(1, 2); // This throws no error, since 1 !== 2
Assert.notDeepEqual(actual, expected[, message])
methodThe assert not deep equality method is used to check for shallow inequality between actual and expected results. If you want to test for comparison among child properties, this method is a great fit for you.
A quick example of how to use the assert.notDeepEqual()
method is shown in the expression below:
//Import module const assert = require('assert'); const val1 = { x: { y: 1 } }; const val2 = { x: { y: 2 } }; const val3 = { x: { y: 1 } }; assert.notDeepEqual(val1, val3); // Returns an error, since val1 is equal to val3 // Values of b are different (Child properties) assert.deepEqual(val1, val2); // Returns no error since the child properties are not equal
In this article, we’ve seen how and why we may need to use the Node.Js assert module in our applications.
It is advised to mainly use assert in strict mode while writing codes for production because their legacy counterparts may produce unexpected results, as they use abstract equality comparison, and because they are current depreciated.
You may be interested in this documentation which explains how to create a call tracker object
, which will verify if invariant expressions were called the number of times required.
Thank you so much for reading this article.
Deploying a Node-based web app or website is the easy part. Making sure your Node instance continues to serve resources to your app is where things get tougher. If you’re interested in ensuring requests to the backend or third-party services are successful, try LogRocket.
LogRocket is like a DVR for web and mobile apps, recording literally everything that happens while a user interacts with your app. Instead of guessing why problems happen, you can aggregate and report on problematic network requests to quickly understand the root cause.
LogRocket instruments your app to record baseline performance timings such as page load time, time to first byte, slow network requests, and also logs Redux, NgRx, and Vuex actions/state. Start monitoring for free.
Would you be interested in joining LogRocket's developer community?
Join LogRocket’s Content Advisory Board. You’ll help inform the type of content we create and get access to exclusive meetups, social accreditation, and swag.
Sign up nowLearn how to implement one-way and two-way data binding in Vue.js, using v-model and advanced techniques like defineModel for better apps.
Compare Prisma and Drizzle ORMs to learn their differences, strengths, and weaknesses for data access and migrations.
It’s easy for devs to default to JavaScript to fix every problem. Let’s use the RoLP to find simpler alternatives with HTML and CSS.
Learn how to manage memory leaks in Rust, avoid unsafe behavior, and use tools like weak references to ensure efficient programs.