Skip to content Skip to sidebar Skip to footer

Simple Way To Test Middleware In Express Without Creating Recreating Server?

I'd like to be able to stub my middleware functions on a per-test basis. The problem, as articulated here, is that I can't just stub my middleware functions since node has cached t

Solution 1:

The problem is not really related to Node caching modules - it's express who stores a reference to a middleware function when a server is initially created. After isAdmin method of required module is stubbed, it's the cached version who gets stubbed, so using a tool like proxyquire would only allow you to require a fresh version of the module (without stubbed method) if you need it for some reason.

If what you're looking for is adjusting behavior of a particular middleware for already created express server, you'd need a way to alter middleware function's behavior by its reference. Hopefully, sinon stubs (and others too, e.g. ones jest provides) are capable of that. However, you still need to stub the module before creating an express server so it stores a reference to the stubbed function.

Sample implementation might look as follows:

const request = require("supertest");
const { expect } = require("chai");
const sinon = require('sinon');
const auth = require ("../utils/auth-middleware");

// store reference to original function in case you need it:const originalIsAdmin = auth.isAdmin// replace isAdmin method with a stubbed, but don't specify implementation yetconst adminStub = sinon.stub(auth, "isAdmin");

// init express server that relies on stubbed `auth.isAdmin` referenceconst app = require("../app.js");

it('this test is using auth.isAdmin that just calls .next()', () => {
  // make middleware just pass
  auth.isAdmin.callsFake((req, res, next) =>next());

  // ...
});

it('this test is using real auth.isAdmin implementation', () => {
  // make middleware call real implementation
  auth.isAdmin.callsFake(originalIsAdmin);

  // ...
});

Solution 2:

Sergey Lapin solution worked great for me for single file test. If you are running multiple test files (with mocha for example) and one of them is stubbing the middleware like Sergey Lapin suggested - callsFake does not work.

Answer : test_config.js

const auth= require('../utils/auth-middleware');
const sinon = require('sinon');

const originalIsAdmin = auth.isAdmin;
const stubbedIsAuth = sinon.stub(auth, 'isAdmin');

const app = require("../app.js");

module.exports = {
    originalIsAdmin,
    stubbedIsAuth,
    app,
};

Inside file A.js whare you need to skip isAdmin:

const { app } = require('./test_config');
const auth= require('../utils/auth-middleware');

// before each test. No other .stubbeforeEach(function () {
            auth.isAdmin.callsFake((req, res, next) =>next());
});

Inside file B.js whare you need original implementation of isAdmin:

const { originalIsAdmin, app} = require('./test_config');

// before each test. No other .stubbeforeEach(function () {
            auth.isAdmin.callsFake(originalIsAdmin);
});

Post a Comment for "Simple Way To Test Middleware In Express Without Creating Recreating Server?"