2

I'm trying to mock the passport.authenticate('local'):

 app.post('/login', passport.authenticate('local'), (req, res, next) => {console.log('should enter');})

Am using Sinon, but the method doesn't execute the console.log inside the login route

beforeEach(function (done) {
      aut = sinon.stub(server.passport, 'authenticate').returns(() => {});
      server.app.on('appStarted', function () {
        done();
      });
    });

afterEach(() => {
  aut.restore();
});

describe('Login', () => {
  it('should login', (done) => {
    chai.request(server.app)
      .post('/login')
      .send({
        username: 'user',
        password: 'pas'
      })
      .end(function (error, response, body) {
        return done();
      });
  });
});

Also, When I put the mock inside the real passport.authenticate('local') like this:

app.post('/login', () => {}, (req, res, next) => {console.log('should enter');})

It still doesn't enter the route which means that the sinon callFake wouldn't help at all. Only if I remove the

passport.authenticate('local')

from the /login route will the 'should login' test enter the route.

Implement sinon in beforeEach

let server = require('../../../app.js');
let expect = chai.expect;
chai.use(chaiHttp);

var aut;
beforeEach(() => {
  aut = sinon.stub(server.passport, 'authenticate').returns((req, res, next) => next());
});

app.js

const app = express();

middleware.initMiddleware(app, passport);

const dbName = 'dbname';
const connectionString = 'connect string';

mongo.mongoConnect(connectionString).then(() => {
        console.log('Database connection successful');
        app.listen(5000, () => console.log('Server started on port 5000'));
    })
    .catch(err => {
        console.error('App starting error:', err.stack);
        process.exit(1);
    });

// If the Node process ends, close the Mongoose connection
process.on('SIGINT', mongo.mongoDisconnect).on('SIGTERM', mongo.mongoDisconnect);

register.initnulth(app);

login.initfirst(app, passport);
logout.initsecond(app);


module.exports = app;
EugenSunic
  • 13,162
  • 13
  • 64
  • 86
  • Isn't your `aut` stub asynchronous? Would you want `.yields` instead of `.returns`? – scniro Feb 04 '19 at 13:49
  • Not sure... how would I apply yield to the passport.authenticate exactly? – EugenSunic Feb 04 '19 at 13:53
  • Can you share the contents of `app.js`? – Brian Adams Feb 07 '19 at 03:50
  • @brian-lives-outdoors, as i said sinon doesn't seem to be working as expected... – EugenSunic Feb 07 '19 at 08:23
  • what does `middleware.initMiddleware(app, passport);`? It seems you don't call the mocked instance there – Alejandro Feb 07 '19 at 08:27
  • @Alex I'll try to see if that causes the issue however still am unsure how sinon wouldn't work here because of it.. – EugenSunic Feb 07 '19 at 11:59
  • It's not the issue. As I said my mock doesn't get applied, sinon.stub(server.passport, 'authenticate').returns((req, res, next) => next()); doesn't replace the real function – EugenSunic Feb 07 '19 at 12:07
  • 1
    @eugensunic `sinon.stub(server.passport, 'authenticate')` will replace the `authenticate` property on the `server.passport` object, but I still can't see where `server.passport` is coming from and if that is the right object to use for the mock. Is the full code available in a repo? – Brian Adams Feb 07 '19 at 18:31
  • @brian-lives-outdoors yes indeed should replace it, I'll double check if the reference to that object is correct. Don't have a repo. Will report... – EugenSunic Feb 07 '19 at 18:34
  • I solved my problem finally by putting login.initfirst(app, passport); inside app.listen callback, after I started my servers only then should I initialise all the components... – EugenSunic Feb 07 '19 at 19:33
  • 1
    @eugensunic glad to hear you got it working – Brian Adams Feb 08 '19 at 03:35

1 Answers1

3

It seems you want to use a middleware callback that does nothing but just lets the request be handled by later middlewares. Such callback would be:

(req, res, next) => next()

The middleware has to call next() for the request continue being processed by later middlewares. So you should setup your stub like this:

aut = sinon.stub(server.passport, 'authenticate').returns((req, res, next) => next());
Louis
  • 146,715
  • 28
  • 274
  • 320
  • it seems that the sinon stub has no effect at all. As I described in my post. The (req, res, next) => next() is the solution (just implemented it in the route) but am not able to put it via sinon, any ideas. Posted some more code where I call sinon... – EugenSunic Feb 04 '19 at 23:58