Mongoose

Mongoose Testing

It's a good practice to write a test before beginning to write the code. This practice helps to ensure that your code is free from bugs. It also ensures that you are not writing more code then you need to to solve the problem at hand.

Since a mocking library for mongodb does not currently, exist we will be interacting with mongo directly for our test. Generally when writing code that interacts with a database it is often advisable to use a mocking library -- something that mimics the database but allows for faster tests. In the future we may add the feature, but for now mongo is fast enough for our purposes.

  1. Clearing the database before each test.

    Since we are using an actual mongodb database for our tests it is important that we clear the database before each tests. This ensures that existing data does not interfere with our test, altering the results.

    To accomplish this we will create a beforeEach method that will be called before each test. Create a file in the test directory called utils.js. We will import this file in each test file. Add the following to this file:

    test/utils.js

     'use strict';
    
     //  Modified from https://github.com/elliotf/mocha-mongoose
    
     var config = require('../config');
     var mongoose = require('mongoose');
    
     // ensure the NODE_ENV is set to 'test'
     // this is helpful when you would like to change behavior when testing
     process.env.NODE_ENV = 'test';
    
     beforeEach(function (done) {
    
       function clearDB() {
         for (var i in mongoose.connection.collections) {
           mongoose.connection.collections[i].remove(function() {});
         }
         return done();
       }
    
       if (mongoose.connection.readyState === 0) {
         mongoose.connect(config.db.test, function (err) {
           if (err) {
             throw err;
           }
           return clearDB();
         });
       } else {
         return clearDB();
       }
     });
    
     afterEach(function (done) {
       mongoose.disconnect();
       return done();
     });
    

    This helpers file, when imported into a test file, will clear the mongodb test database of any previous collections.

  2. Create our first test:

    Add the following to:

    test/users/models.js

     'use strict';
    
     // import the moongoose helper utilities
     var utils = require('../utils');
     var should = require('should');
     // import our User mongoose model
     var User = require('../../users/models').User;
    
     describe('Users: models', function () {
    
       describe('#create()', function () {
         it('should create a new User', function (done) {
           // Create a User object to pass to User.create()
           var u = {
             name: {
               givenName: 'Barack',
               familyName: 'Obama'
             }
           };
           User.create(u, function (err, createdUser) {
             // Confirm that that an error does not exist
             should.not.exist(err);
             // verify that the returned user is what we expect
             createdUser.name.givenName.should.equal('Barack');
             createdUser.name.familyName.should.equal('Obama');
             // Call done to tell mocha that we are done with this test
             done();
           });
         });
       });
    
     });
    
    
  3. Run the test.

    Make sure that mongodb is running:

     mongod
    

    And restart the test runner:

     npm test
    

    You should see a failing test:

     addition
       ✓ should add 1+1 correctly
     Users: models
       #create()
         1) should create a new User
    
     ✖ 1 of 2 tests failed:
    
     1) Users: models #create() should create a new User:
        TypeError: Cannot call method 'create' of undefined
    

    This is because we have not yet created our User model. Lets do that now.

Resources

Comments