mokiliii Lo
mokiliii Lo

Reputation: 637

How to test simple middleware

I have a 3 middlewares like this:

module.exports = {

    validateRequest: function(req, res, next) {
        return new Promise((resolve, reject) => {
            if(!req.body.title || !req.body.location || !req.body.description || !req.body.author){
            Promise.reject('Invalid')
            res.status(errCode.invalid_input).json({
              message: 'Invalid input'
            })
         }
     })
    },
    sendEmail: ...,
    saveToDatabase: ...

}

I use those in my route like this:

const { validateRequest, sendEmail, saveToDatabase } = require('./create')
...
api.post('/create', validateRequest, sendEmail, saveToDatabase);

It works, but I can't test it. Here's my (failed) attempt:

test('create.validateRequest should throw error if incorrect user inputs', (done) => {
  const next = jest.fn();
  const req = httpMocks.createRequest({ 
    body: { 
            title: 'A new world!',
            location: '...bunch of talks...',
            description: '...'  
    }
  });
  const res = httpMocks.createResponse();
  expect(validateRequest(req, res, next)).rejects.toEqual('Invalid')

})

Jest outputs this:
Error
Invalid

Question: How can I test this validateRequest middleware?

Upvotes: 0

Views: 425

Answers (1)

James
James

Reputation: 82096

So firstly, assuming this is Express, there's no reason (or requirement) to return a Promise from your middleware, return values are ignored. Secondly, your current code will actually cause valid requests to hang because you aren't calling next to propagate the request to the next middleware.

Taking this into account, your middleware should look a bit more like

validateRequest: (req, res, next) => {
  if (!req.body.title || !req.body.location || !req.body.description || !req.body.author) {
    // end the request
    res.status(errCode.invalid_input).json({
      message: 'Invalid input'
    });
  } else {
    // process the next middleware
    next();
  }
},

Based on the above, a valid unit test would look like

test('create.validateRequest should throw error if incorrect user inputs', () => {
  const next = jest.fn();
  const req = httpMocks.createRequest({ 
    body: { 
      title: 'A new world!',
      location: '...bunch of talks...',
      description: '...'  
    }
  });
  const res = httpMocks.createResponse();
  validateRequest(req, res, next);
  // validate HTTP result
  expect(res.statusCode).toBe(400);
  expect(res._isJSON()).toBeTruthy();
  // validate message
  const json = JSON.parse(res._getData());
  expect(json.message).toBe('Invalid input');
})

Upvotes: 2

Related Questions