How to use mocha with mongoose ? - GeeksforGeeks

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 promisesmongoose.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 dataconst 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 modelconst 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 testbeforeEach(() => {    // 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.
Mongoose
NodeJS-Questions
Picked
MongoDB
Node.js
Web Technologies
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
How to connect MongoDB with ReactJS ?
MongoDB - limit() Method
MongoDB - FindOne() Method
Create user and add role in MongoDB
MongoDB updateOne() Method - db.Collection.updateOne()
Installation of Node.js on Linux
Node.js fs.readFileSync() Method
How to update Node.js and NPM to next version ?
Node.js fs.readFile() Method
Node.js fs.writeFile() Method