Unit Test your Mongoose Model Using Jest

Nwachukwu Chibuike
JavaScript in Plain English
6 min readAug 23, 2021
Photo by Sigmund on Unsplash

Oftentimes, we create mongoose models, start up our servers, and never bother to test if the models actually work independently from the server as they should.

This article will show how to unit test your Mongoose model using Jest.

Installing Dependencies

We would set up a basic project containing our model and test files. We initialize a node project and install all necessary dependencies.

npm init -y
npm i mongoose crypto jest mongodb-memory-server

So what do we have here?

Mongoose: We would use mongoose to interface with our mongo database.

crypto: We use this to hash our password, you would see its use later in the tutorial.

Jest: The testing library we would be making use of. If you would like to read more about jest and see its features, check this.

mongodb-memory-server: This is an in-memory version of a mongo database that we would use. This saves us from the stress of having to set up a real mongo database. This also connects to the device’s main memory and is not stored physically to disk, hence it's faster and better for testing. You can read more about this package here.

Project structure

Next, we proceed to create our code structure. Since we are only focused on testing mongoose models, we would create our models and some methods in them.

For this example, we would be creating only one model: Users model.

Create a new folder called models; then create a file under it called user.js. Your code structure should look similar to this:

Project structure

User Schema

In the newly created user.js file, we add the following code:

In the above code, we set a user schema in mongoose and create two methods: setPassword and validatePassword. We use these methods to generate a hashed user password and also validate a user's password respectively.

Setting up the Test environment

Before we write our test, we would need to integrate our mongo memory server into our project. To do this we create a new folder called db at the base of our project, then inside that folder create a new file called setup.js.

Our new code structure should look like this:

project structure with db.js

Next, open up db.js and add this code. I would explain what happens here shortly:

Explanation

We first and foremost import our two dependencies which are mongoose and MongoMemoryServer.

Next, we create 3 methods, namely setUp, dropDatabase, and dropCollections.

The setUp method is where we connect to the database using the MongoMemoryServer package.

The dropDatabase method is used to drop the database entirely, close, and stop the connection.

The dropCollections method is used to remove all collections from our db.

Lastly, we export these 3 methods as we would be needing them in our test file.

Writing our test

The moment we have been waiting for is finally here. We get to write some test!

I personally love keeping my tests in the same folder with the file it would be testing, this is a personal choice of mine and isn't mandatory.

That been said, we would create a new file called user.test.js in the same folder where we have the user.js file.

Our new project stricture should now be:

Project structure with user.test.js

Now add this code below to the newly created user.test.js file.

Explanation

Looks quite a lot right? Well, let's get into it already.

In the first section, we import our db setup file, User model, and also mongoose.

Next, we create dummy data and store it in userData, we would use this to carry out our test later in this file.

Next, we add three methods namely, beforeAll, afterEach, afterAll, these methods are allowed in jest.

The beforeAll would be executed before our test suites run. In this case, we have only one describe block. At this method, we call the db.setUp to set up our db connection.

The afterEach runs after each test suite. If we had multiple describe blocks, we would use this method to prevent each suite from affecting the result of another. This happens because we call the db.dropCollection which removes all collections from the db.

The afterAll after all test suites have finished. This is where we drop the db and close the connection using the db.dropDatabase method.

Next, we created a test suite and write three tests in it.

The first test block: create & save user successfully, we create a new user and then check if indeed a user was created. If you recall in our schema, a user has email, phone, and salt properties, so we check if these properties exist in the returned user data, in the case of phone and email, checking if what was returned was indeed what we saved!. Also since mongoose attaches an _id property to a schema we check if that exists likewise.

The second test block: insert user successfully, but the field not defined in schema should be undefined, we create a new user, but this time we pass a property that doesn't exist in the schema. We expect the user to be created, but this property is not added, hence we test to make sure it isn't in the data returned, by expecting it to be undefined.

The third test block: create user without required field should failed, we create a new user as the previous test, but this time we don't pass the email property, and since it is required in our schema, mongoose shouldn't create that particular user. We wrap the save method in a try and catch and check if the error got is indeed a mongoose validation error and further check that this validation error was caused by the missing email property.

Run the test

To run our test we would need to update our package.json file and add single script commands to the scripts section. This script tells jest how to run our test and where to find our test files.

"scripts": {"test": "jest --runInBand ./models"},

The runInBand flag simply tells jest to run all our tests serially in the current process, rather than creating a worker pool of child processes. Very useful for debugging.

The ./models simply tell jest to run all test files found in the models folder.

Check out the Jest CLI documentation here to see more options that can be used.

To run our test we run the test script found in our package.json file:

npm run test

If you followed along properly, you should get these lovely green ticks, with a terminal display as the below:

Test success

Wolla! You just ran your tests and they all passed!

I can’t wait to see what you build and test! Go catch that bug in your mongoose model.

The complete code can be found here. Have a blast!

In Plain English 🚀

Thank you for being a part of the In Plain English community! Before you go:

Sign up to discover human stories that deepen your understanding of the world.

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

--

--

Published in JavaScript in Plain English

New JavaScript and Web Development content every day. Follow to join our 3.5M+ monthly readers.

Written by Nwachukwu Chibuike

Full-stack developer, technical writer and lover of Jamstack. Passionate about lifelong learning.

Responses (3)

Write a response