简体   繁体   中英

Node / Express / Mocha disable middleware?

I have a hello world app which looks like this:

let clientAuthMiddleware = () => (req, res, next) => {
  if (!req.client.authorized) {
    return res.status(401).send('Invalid client certificate authentication.');
  }
  return next();
};

function app() {
    const fs = require('fs');
    const https = require('https');
    const express = require('express');

    const app = express();
    app.use(clientAuthMiddleware());

    app.get('/', (req, res) => {
      console.log(req.socket.getPeerCertificate());
      return res.send('Hello world!');
    });

    https
      .createServer(
        {
          cert: fs.readFileSync('cert/localhost.crt'),
          key: fs.readFileSync('cert/localhost.key'),        
          requestCert: true,
          rejectUnauthorized: false,
          ca: fs.readFileSync('cert/ca.crt'),
        },
        app
      )
      .listen(9443);
    
    return app;
}

if (require.main === module) instance = app()
module.exports.app = app
module.exports.authMiddleware = clientAuthMiddleware

And a test which looks like:

 describe('GET /', function() {
    it('should return Hello world!', function(done) {
          chai.request(app.app()).get('/')
             .end((err, res) => {
                 if (err)done(err);
                 res.should.have.status(200);
                 expect(res.body).to.equal('Hello world!');
                 done();
              });
    });
  });

How can I replace authMiddleware in the test, preferably without using some external stubbing library? Isn't there some way I can just rearrange my code so in the test I can just do app.authMiddleware = {my own stub function}?

Edit: Also, is there a way I can just straightforwardly unit test these endpoints like app.get('/') without making a real HTTP request? I keep searching Google for unit testing Node/Express with Mocha and every resource I find seems to be functional testing making a real request....

You can specify in your app using environment variables, if your environment is test or production or development. write condition fro middlware something like this

 if(process.env.NODE_ENV !== 'test') { 
        app.use(clientAuthMiddleware()); 
 } 

And if you want to test your app without making HTTP request, you need to separate the business logic from request handlers.

For example if you have a route "/api/user/login", for the route you have a route hanlder something like

 app.post("/api/user/login" , async (req,res) => {
    const response = await login(req.body.email,req.body.password);
    res.status(200).json(response);
 });

 // login function is independent of express 
 // routes and can be easily tested  without api requests
 async function login(email,password) {
    //login logic
 }

In this way you can make your business logic independent of express and it can be easily tested without HTTP requests.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM