express middleware testing mocha chai

I used node-mocks-http to unit test my middleware. Here's my code:

function responseMiddleware(req, res, next) {    
    res.sendResponse = (...args) => { 
        //<==== Code removed from here
    };
    next();
}

And in my spec file I did it like this:

var expect = require('chai').expect;
var sinon  = require('sinon');    
var responseMiddleware = require('./response');
var httpMocks = require('node-mocks-http');


    describe('request handler calling', function() {
      it('should call next() once', function() {        
        var nextSpy = sinon.spy();

        responseMiddleware({}, {}, nextSpy);
        expect(nextSpy.calledOnce).to.be.true;
      });
      it('should add sendResponse key', function() {
        var nextSpy = sinon.spy();
        var req = httpMocks.createRequest();
        var res = httpMocks.createResponse();

        responseMiddleware(req, res, nextSpy);
        expect(nextSpy.calledOnce).to.be.true;
        responseMiddleware(req, res, () => {
            expect(res).to.have.property('sendResponse');        
        })        
      });
    });

If you are using async calls then you can use await and then call done() after that.


Here's a simple setup that you could use, using chai and sinon:

var expect = require('chai').expect;
var sinon  = require('sinon');

var middleware = function logMatchingUrls(pattern) {
    return function (req, res, next) {
        if (pattern.test(req.url)) {
            console.log('request url', req.url);
            req.didSomething = true;
        }
        next();
    }
}

describe('my middleware', function() {

  describe('request handler creation', function() {
    var mw;

    beforeEach(function() {
      mw = middleware(/./);
    });

    it('should return a function()', function() {
      expect(mw).to.be.a.Function;
    });

    it('should accept three arguments', function() {
      expect(mw.length).to.equal(3);
    });
  });

  describe('request handler calling', function() {
    it('should call next() once', function() {
      var mw      = middleware(/./);
      var nextSpy = sinon.spy();

      mw({}, {}, nextSpy);
      expect(nextSpy.calledOnce).to.be.true;
    });
  });

  describe('pattern testing', function() {
    ...
  });

});

From there, you can add more elaborate tests for the pattern matching, etc. Since you're only using req.url, you don't have to mock an entire Request object (as created by Express) and you can just use a simple object with a url property.