Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to trigger Express error middleware?

I'm trying to unit test this piece of code in Mocha:

app.use(function (err, req, res, next) {
    console.error(err.stack)
    res.status(500).send('Something broke!')
})

I don't know how to get my request inside a Mocha unit test to trigger it.

like image 432
Eugene Fedotov Avatar asked Aug 20 '17 16:08

Eugene Fedotov


People also ask

How do I catch error in middleware Express?

For errors returned from asynchronous functions invoked by route handlers and middleware, you must pass them to the next() function, where Express will catch and process them. For example: app. get('/', function (req, res, next) { fs.

How do I use Express Async error?

To handle an error in an asynchronous function, you need to catch the error first. You can do this with try/catch . Next, you pass the error into an Express error handler with the next argument. If you did not write a custom error handler yet, Express will handle the error for you with its default error handler.


1 Answers

First I would break out the middleware into its own file/function. As it sits, it's "integrated" with the Express app. So you're not testings only the error middleware, but also the Express app instance to an extent.

With that said, decouple the error middleware from the Express app:

src/middleware/error-handler.js

module.exports = (err, req, res, next) => {
  console.error(err.stack)
  res.status(500).send('Something broke!')
}

You will still .use() it in the main app.js or wherever you setup Express:

const express = require('express')
const errorHandler = require('./src/middleware/error-handler')
const app = express()

app.use(errorHandler)

But now we're free of the Express dependency and we have a simple function we can isolate and test. Below is a simple test with Jest which you can easily adjust to work with Mocha.

__tests__/middleware/error-handler.test.js

const errorHandler = require('../../src/middleware')

describe('middleware.ErrorHandler', () => {
  /**
   * Mocked Express Request object.
   */
  let req

  /**
   * Mocked Express Response object.
   */
  let res

  /**
   * Mocked Express Next function.
   */
  const next = jest.fn()

  /**
   * Reset the `req` and `res` object before each test is ran.
   */
  beforeEach(() => {
    req = {
      params: {},
      body: {}
    }

    res = {
      data: null,
      code: null,
      status (status) {
        this.code = status
        return this
      },
      send (payload) {
        this.data = payload
      }
    }

    next.mockClear()
  })

  test('should handle error', () => {
    errorHandler(new Error(), req, res, next)

    expect(res.code).toBeDefined()
    expect(res.code).toBe(500)

    expect(res.data).toBeDefined()
    expect(res.data).toBe('Something broke!')
  })
})
like image 178
Francisco Mateo Avatar answered Sep 18 '22 10:09

Francisco Mateo