H_H
H_H

Reputation: 1610

how to mock configurable middleware in node js with sinon and mocha

I have configurable middleware where I can pass parameters and based on that it calls next function.

middleware code:

File: my-middleware.js

exports.authUser = function (options) {
  return function (req, res, next) {
    // Implement the middleware function based on the options object
    next()
  }
}

var mw = require('./my-middleware.js')

app.use(mw.authUser({ option1: '1', option2: '2' }))

How to mock the middleware using sinon js?

I have done in this way but, it throwing me "TypeError: next is not a function".

Here is my unit test code:

  it("Should return data by id", (done: any) => {

        sandbox.stub(mw, 'authUser')
            .callsFake((req: any, res: any, next: any) => { return next(); });

        server = require('../../index');

        let req = {
            "id": '123'
        }

        chai.request(server)
            .post("/user")
            .send(req)
            .end((request, res) => {

                expect(res.status).to.equal(200);
                expect(res.body.success).to.equal(true);

                done();
            });
    });

Can you help me to mock the configurable middleware? Thanks in advance!!

Upvotes: 1

Views: 2457

Answers (2)

Lin Du
Lin Du

Reputation: 102207

The authUser is a high order function, so you need to stub it for this.

E.g.

mws.js:

exports.authUser = function(options) {
  return function(req, res, next) {
    // Implement the middleware function based on the options object
    next();
  };
};

app.js:

const express = require('express');
const mws = require('./mws');
const app = express();

app.use(mws.authUser({ option1: '1', option2: '2' }));

app.post('/user', (req, res, next) => {
  res.json({ success: true });
});

module.exports = app;

app.integration.test.js:

const chai = require('chai');
const chaiHttp = require('chai-http');
const sandbox = require('sinon').createSandbox();
const mws = require('./mws');

chai.use(chaiHttp);
const expect = chai.expect;

describe('61818474', () => {
  afterEach(() => {
    sandbox.restore();
  });
  it('Should return data by id', (done) => {
    sandbox.stub(mws, 'authUser').callsFake((options) => (req, res, next) => {
      return next();
    });
    const server = require('./app');
    const req = { id: '123' };
    chai
      .request(server)
      .post('/user')
      .send(req)
      .end((request, res) => {
        expect(res.status).to.equal(200);
        expect(res.body.success).to.equal(true);
        sandbox.assert.calledWith(mws.authUser, { option1: '1', option2: '2' });
        done();
      });
  });
});

integration test results with coverage report:

  61818474
    ✓ Should return data by id (257ms)


  1 passing (265ms)

----------|---------|----------|---------|---------|-------------------
File      | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
----------|---------|----------|---------|---------|-------------------
All files |      80 |      100 |   33.33 |      80 |                   
 app.js   |     100 |      100 |     100 |     100 |                   
 mws.js   |   33.33 |      100 |       0 |   33.33 | 2-4               
----------|---------|----------|---------|---------|-------------------

Upvotes: 2

Yak O'Poe
Yak O'Poe

Reputation: 822

By specifying jestjs in your tags... I guess you might want to use additional functions that Jest gives you for free. You don't really need Sinon in this case, Jest has its own way to mock/stub (entire modules too), something like jest.mock('moduleName').

You might want to check the following link for useful examples and possible usages: https://jestjs.io/docs/en/manual-mocks

Upvotes: 0

Related Questions