javascriptnode.jsunit-testingsinonnode-mongodb-native

Sinon stub out module's function from a middleware


Based on this question, I need to also make a test for a middleware which also uses the db-connection.js file. The middleware file will look like this:

const dbConnection = require('./db-connection.js')

module.exports = function (...args) {
   return async function (req, res, next) {
      // somethin' somethin' ...
      const dbClient = dbConnection.db
      const docs = await dbClient.collection('test').find()
 
      if (!docs) {
         return next(Boom.forbidden())
      }
   }
}

, the database connection file do not change, which is:

const MongoClient = require('mongodb').MongoClient
const dbName = 'test'
const url = process.env.MONGO_URL

const client = new MongoClient(url, { useNewUrlParser: true,
  useUnifiedTopology: true,
  bufferMaxEntries: 0 // dont buffer querys when not connected
})

const init = () => {
  return client.connect().then(() => {
    logger.info(`mongdb db:${dbName} connected`)

    const db = client.db(dbName)
  })
}

/**
 * @type {Connection}
 */
module.exports = {
  init,
  client,
  get db () {
    return client.db(dbName)
  }
}

How the middleware works is by passing list of strings (that strings is roles), I have to query to the database and check whether there is a record of each roles. If the record exists, I will return next(), while if the record does not exist, I will return next(Boom.forbidden()) (next function with a 403 status code from Boom module).

Given the details above, how does one make a test to test out the return value of the middleware if the record exists or not? This means I have to assert the next() and next(Boom.forbidden) to be exact.


Solution

  • Based on the answer. You can create stubs for the req, res objects, and next function.

    E.g.(Doesn't run, but it should work.)

    const sinon = require('sinon');
    
    describe('a', () => {
      afterEach(() => {
        sinon.restore();
      });
      it('should find some docs', async () => {
        process.env.MONGO_URL = 'mongodb://localhost:27017';
        const a = require('./a');
        const dbConnection = require('./db-connection.js');
    
        const dbStub = {
          collection: sinon.stub().returnsThis(),
          find: sinon.stub(),
        };
        sinon.stub(dbConnection, 'db').get(() => dbStub);
        const req = {};
        const res = {};
        const next = sinon.stub();
        const actual = await a()(req, res, next);
        sinon.assert.match(actual, true);
        sinon.assert.calledWithExactly(dbStub.collection, 'test');
        sinon.assert.calledOnce(dbStub.find);
        sinon.assert.calledOnce(next);
      });
    });