Alex J Alex J - 3 months ago 16
Node.js Question

How to test express middleware that depends on other vendor middleware?

I wanna test a middleware function that inside calls a vendor middleware function. The middleware is:

const expressJwt = require('express-jwt');
const validateJwt = expressJwt({ secret: 'whatever' });

exports.isAuthenticated = (req, res, next) => {
if (req.query && req.query.hasOwnProperty('access_token')) {
req.headers.authorization = `Bearer ${req.query.access_token}`;
}

validateJwt(req, res, next);
};


I've tried to create a
sinon.spy()
object and pass it as
next
parameter, but is not called apparently.

Another approach I've tried is to check if exists
req.user
, since the purpose of the
express-jwt
middleware is to validate and attach
user
to the
req
object. No luck with this neither.

I've seen the existence of
chai-connect
, but not sure how to use it.

Any ideas? Highly appreciate it!

Answer

I finally managed to do it with proxyquire and chai-connect:

In your mocha config:

chai.use(require('chai-connect-middleware'));
global.connect = chai.connect;

In your test:

describe('isAuthenticated', () => {
// Wrap call to chai.connect into a function to use params and return a Promise
const mockedMiddleware = (changeSecret) => {
  let oldToken;
  if (changeSecret) {
    oldToken = acessToken;
    acessToken = 'blabalblalba';
  }

  return new Promise((resolve, reject) => {
    connect.use(middleware.isAuthenticated)
      .req(req => {
        req.query = { access_token: acessToken };
      })
      .next((res) => {
        acessToken = oldToken;
        if (res && res.status === 401) {
          reject(res.message);
        } else {
          resolve();
        }
      })
      .dispatch();
  });
};

it('should validate correctly', () =>
  mockedMiddleware().should.be.fulfilled
);

it('should not validate', () =>
  mockedMiddleware(true).should.be.rejected
);
});