如何触发Express错误中间件?

Eug*_*tov 3 unit-testing mocha.js node.js express supertest

我正在尝试对Mocha中的这段代码进行单元测试:

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

我不知道如何在Mocha单元测试中获取我的请求以触发它。

Fra*_*teo 5

首先,我将中间件分解为自己的文件/功能。就目前而言,它已与Express应用程序“集成”在一起。因此,您不仅要在某种程度上测试错误中间件,而且还要测试Express应用程序实例。

如此说来,将错误中间件与Express应用程序分离:

src/middleware/error-handler.js

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

您仍然.use()可以在主要app.js或任何安装Express的地方使用它:

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

app.use(errorHandler)
Run Code Online (Sandbox Code Playgroud)

但是现在我们摆脱了Express依赖,我们有了一个可以隔离和测试的简单函数。以下是使用Jest进行的简单测试,您可以轻松调整以使用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!')
  })
})
Run Code Online (Sandbox Code Playgroud)