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.