How to use mocha with mongoose ?
Last Updated :
14 Apr, 2021
Mocha: Mocha is a testing framework that is used to perform tests within our application.It makes sure everything works correctly.
‘Mocha in Node.js’ means using the mocha unit testing framework in Node.js runtime environment. Mocha has tons of great features.
Key Features:
- Simple async support.
- Async test timeout support.
- Use any assertion library you want
- Before, after, before each, after each hooks are very useful to clean the environment with each test.
If you are not familiar with mongoose, click here.
Throughout some stretch of time, our application will have a greater number of lines of code for testing than the real application rationale. So it's consistently something to be thankful for to compose tests and follow a Test Driven Development or TDD approach.
In this post, we will set up a fundamental testing suite to make our Create Read Update and Delete (CRUD) procedure on the MongoDB data set with the Mongoose library utilizing the most well-known Mocha testing structure.
Installing Modules:
npm i mocha mongoose
Folder structure: We'll create all out test files in the test directory.
In our Node.js-MongoDB project, we'll be using this helper file for creating connection. If you are new to MongoDB check this post.
test_helper.js
// test/test_helper.js
const mongoose = require('mongoose');
// tells mongoose to use ES6 implementation of promises
mongoose.Promise = global.Promise;
const MONGODB_URI = 'mongodb://mongodb0.example.com:27017';
mongoose.connect(MONGODB_URI);
mongoose.connection
.once('open', () => console.log('Connected!'))
.on('error', (error) => {
console.warn('Error : ', error);
});
// runs before each test
beforeEach((done) => {
mongoose.connection.collections.users.drop(() => {
done();
});
});
We'll be using the beforeEach() hook to empty our DB before our tests run. Deletion takes time, so we need to hold mocha before the operation finishes. Calling the done() function tells that the operation is finished now and we can continue the execution.
The .on() and .once() are the event handlers. They take the event as the first argument and a function as the second argument which executes once the event occurs.
Our MongoDB Schema:
user.js
// Inside schema/user.js
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const UserSchema = new Schema({
name: {
type: String,
required: [true, 'Name is required.']
},
age: Integer
})
// it represents the entire collection of User data
const User = mongoose.model('User', UserSchema);
module.exports = User;
Now, we need a script in our package.json file to start the test.
"scripts": {
"test" : "mocha --recursive --exit"
}
In --recursive means it will recursively test inside the test directory and --exit to exit whenever all tests have been executed. Use the following command to run tests using Mocha.
npm run test
Mocha provides us a describe() function which takes a string as the first parameter which is used to identify the group of tests that are passing or failing, and the testing logic is implemented as a function in the second parameter of describe().
The describe() may contain multiple tests inside an it() method or nested describe() functions as well. In our case, we will be making different files for each CRUD operation in MongoDB. Alternatively, we could have used a single file with different describe blocks.
As every test needs us to assert something, Mocha allows us to use many assertion libraries. Here we’ll be using Node.js’ built-in assert module.Â
By adding done() to it() in a test callback, Mocha will know that this test has been completed.
Â
create_test.js
//import the User model
const User = require('../schema/user');
const assert = require('assert');
describe('Creating documents in MongoDB', () => {
it('Creates a New User', (done) => {
const newUser = new User({ name: 'Shriyam' });
newUser.save() // returns a promise after some time
.then(() => {
//if the newUser is saved in db and it is not new
assert(!newUser.isNew);
done();
});
});
});
read_test.js
const User = require('../schema/user');
const assert = require('assert');
let user;
// this will run before running every test
beforeEach(() => {
// Creating a new Instance of User Model
user = new User({ name: 'Shriyam' });
user.save()
.then(() => done());
});
describe('Reading Details of User', () => {
it('Finds user with the name', (done) => {
User.findOne({ name: 'Shriyam' })
.then((user) => {
assert(user.name === 'Shriyam');
done();
});
})
})
delete_test.js
const User = require('../schema/user');
const assert = require('assert');
describe('Deleting a User', () => {
let user;
beforeEach((done), () => {
// user is an instance of User Model
user = new User({ name: 'Shriyam' });
user.save()
.then(() => done());
});
it('Removes a User using its instance', (done) => {
User.remove()
// Checking if the user was deleted from DB or not
.then(() => User.findOne({ name: 'Shriyam' }))
.then((user) => {
assert(user === null);
done();
});
});
it('Removes a user', (done) => {
User.findOneAndRemove({ name: 'Shriyam' })
.then(() => User.findOne({ name: 'Shriyam' }))
.then((user) => {
assert(user === null);
done();
});
});
it('Removes a user using its id', (done) => {
User.findIdAndRemove(user._id)
.then(() => User.findOne({ name: 'Shriyam' }))
.then((user) => {
assert(user === null);
done();
});
})
})
update_test.js
const Username = require('../schema/user');
const assert = require('assert');
describe('Deleting a user', () => {
let user;
beforeEach((done) => {
user = new User({ name: 'Shriyam' });
user.save()
.then(() => done());
});
// Handling Redundant Code
function helperFunc(assertion, done) {
assertion
.then(() => User.find({}))
.then((users) => {
assert(users.length === 1);
assert(users[0].name === 'Updated Shriyam');
done();
});
}
it('Sets and saves a user using an instance', (done) => {
// Not yet updated in MongoDb
user.set('name', 'Updated Shriyam');
helperFunc(user.save(), done);
});
it('Update a user using instance', (done) => {
helperFunc(user.update({ name: 'Updated Shriyam' }), done);
});
});
So, we have now learned how to create Unit Tests using Mocha with Mongoose.
Tip: Use mockgoose library to use a Dummy MongoDB Database so that your original DB stays clean.
Similar Reads
How to Use MongoDB and Mongoose with Node.js ?
MongoDB is a popular NoSQL database that offers flexibility and scalability, making it an excellent choice for modern applications. Mongoose, a powerful ODM (Object Data Modeling) library, simplifies the interaction between MongoDB and Node.js by providing a schema-based solution for data validation
6 min read
Using Mongoose with NestJS
NestJS is a progressive Node.js framework for building efficient, reliable, and scalable server-side applications. It provides a solid foundation for backend development with TypeScript support, built-in decorators, and a modular architecture. Mongoose, on the other hand, is a powerful Object Data M
3 min read
How to Use Mongoose Without Defining a Schema?
Mongoose is a powerful and flexible Node.js library that simplifies interactions with MongoDB. Typically, when working with Mongoose, you define a schema to structure your data before interacting with the database. when using Mongoose, developers define a schema to structure their data, ensuring con
4 min read
How to Register Schema in Mongoose?
In Mongoose, schema registration is a crucial step in defining the structure of our MongoDB documents. In this article, We will go through the process of registering a schema in Mongoose by providing various methods with implementation to efficiently manage our data models. How to register Schema in
3 min read
How To Use the MongoDB Shell
The MongoDB Shell, also known as mongosh is a powerful command-line interface that allows users to interact with MongoDB databases. It provides a REPL (Read-Eval-Print Loop) environment that facilitates database management, data manipulation, and administrative tasks with easeIn this comprehensive g
7 min read
Connect MongoDB with Node App using MongooseJS
The process of integrating MongoDB, a NoSQL database, with a Node.js application using MongooseJS, a MongoDB object modelling tool designed to work in an asynchronous environment. Prerequisites:NodejsnpmMongoDBMongooseJSSteps to connect MongoDB with Node AppFollowing are the steps to connect MongoDB
4 min read
How does Query.prototype.map() works in Mongoose ?
The Query.prototype.map() function is used to run a function fn and treats the return value of fn as the new value for the query to resolve to. All the function which are passed to map() function will be run after any post hooks. Syntax:  Query.prototype.map() Parameters: This function has one par
3 min read
How to update record without objectID in mongoose?
Mongoose is an ODM(Object Data Library) for MongoDB in Node JS that helps to write schema, validation and business logic in a simple way without the hassle of native MongoDB boilerplate. PrerequisitesUnderstanding of Mongoose and MongoDBData Modeling and Schema DesignMongoose Query MethodsApproach t
3 min read
How does Query.prototype.mod() work in Mongoose?
The Query.prototype.mod() function is used to specify a $mod condition. This function basically filters documents for documents whose path property is a number that is equal to remainder modulo divisor. Syntax:  Query.prototype.mod() Parameters: This function has one optional path parameter and an
2 min read
Mongoose prototype.$set() Method
In Mongoose, the prototype.$set() method is a crucial function that allows developers to update specific fields of a document in a MongoDB collection. This method enables atomic modification of field values within a document, offering precise control over your MongoDB data. This article explains how
5 min read