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.
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.
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.
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!')
})
})
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With