Tom Sitter
Tom Sitter

Reputation: 1102

NodeJS and Express -- How to mock token authentication middleware for testing?

I'm making an REST API that uses JWTs for authentication, but to test my endpoints I want to mock the middleware that verifys the JWTs.

I've defined a middleware for checking the token:

// middlewares/auth.js

nJwt = require('njwt');
nconf = require('nconf');

module.exports = {
    verifyToken: function(req, res, next) {
        // check header or url parameters or post parameters for token
        var token = req.body.token || req.query.token || req.headers['x-access-token'];

        // decode token
        if (token) {

            // verifies secret and checks exp
            nJwt.verify(token, nconf.get("auth:secret"), function(err, verifiedJwt) {
              if (err) {
                return res.json({ success: false, message: 'Failed to authenticate token.' });
              } else {
                // if everything is good, save to request for use in other routes
                req.userId = verifiedJwt.body.sub;
                next();
              }
            });

        } else {
            // if there is no token
            // return an error
            return res.status(403).send({
                success: false,
                message: 'No token provided.'
            });

        }
    }
}

Then in my routers I can import and use this middleware on protected endpoints

// routes/someRoutes.js

var router = require('express').Router();
var verifyToken = require('../middlewares/auth').verifyToken;

router.use(verifyToken);

// define routes

Now I want to mock this middleware out so that I can test the endpoints without need a valid token. I've tried doing using chai/mocha/sinon but don't have much luck

// tests/someRoutes.js

var auth = require('../middlewares/auth');
var sinon = require('sinon');

describe('someRoute', function() {
    var verifyTokenStub; 

    before(function (done) {
        verifyTokenStub = sinon.stub(auth, 'verifyToken', function(req, res, next) {
            req.userId='test-id';
            next();
        });
    });
});

But this is still calling the original verifyToken method. Any help is much appreciated!

Upvotes: 1

Views: 5264

Answers (1)

galkin
galkin

Reputation: 5519

  1. Change your middlewares/auth.js file check process.env.NODE_ENV.

Example:

// middlewares/auth.js
...
    // decode token
    if (token || process.env.NODE_ENV === 'test') {//Changes in this string

      // verifies secret and checks exp
      nJwt.verify(token, nconf.get("auth:secret"), function(err, verifiedJwt) {
...
  1. If you use supertest or package with same functionality, the run mocha with environment variable - NODE_ENV=test mocha.

  2. If testing your application with full run, then you should start it with environment variable - NODE_ENV=test npm start.

It's not mocking, but I hope it will help you.

Upvotes: 6

Related Questions