【问题标题】:How to test express middleware error handler with jest and TypeScript如何使用 jest 和 TypeScript 测试 express 中间件错误处理程序
【发布时间】:2021-04-29 18:10:45
【问题描述】:

我对用 jest 测试中间件完全不熟悉

中间件

import HttpException from "../common/http-exception";
import { Request, Response, NextFunction } from "express";

export const errorHandler = (
  error: HttpException,
  request: Request,
  response: Response,
  next: NextFunction
) => {
  const status = error.statusCode || error.status || 500;

  response.status(status).send(error);
};

错误的测试给出错误 TypeError: Cannot read property 'send' of undefined

import HttpException from "../src/common/http-exception";
import { NextFunction, Request, Response, response } from "express";
import { errorHandler } from "../src/middleware/error.middleware";

describe("Error handler middleware", () => {
  const error: HttpException = {
    name: "error",
    statusCode: 500,
    status: 1,
    message: "string",
    error: "string"
  };
  let mockRequest: Partial<Request>;
  let mockResponse: Partial<Response>;
  let nextFunction: NextFunction = jest.fn();

  beforeEach(() => {
    mockRequest = {};
    mockResponse = {
      status: jest.fn()
    };
  });

  test("handle error", async () => {
    errorHandler(
      error as HttpException,
      mockRequest as Request,
      mockResponse as Response,
      nextFunction
    );

    expect(response).toBe(500);
  });
});

还有 HttpException 的打字稿

export default class HttpException extends Error {
  statusCode?: number;
  status?: number;
  message: string;
  error: string | null;

  constructor(statusCode: number, message: string, error?: string) {
    super(message);

    this.statusCode = statusCode;
    this.message = message;
    this.error = error || null;
  }
}

【问题讨论】:

  • 请求和响应未定义的,你有lets但没有任何
  • 我希望 response 的值来自中间件,这可能吗?
  • 怎么样?您直接使用(未定义的)mockResponse 调用它,任何其他值来自哪里?
  • Itried with beforeEach(() => { mockRequest = {}; mockResponse = { status: jest.fn() }; });
  • 好的,请edit这个问题更新现在发生的事情。想想响应实际上是如何使用的。

标签: typescript ts-jest


【解决方案1】:

在您的处理程序中,您调用response.status(status).send(error);,这意味着.status() 应该返回一个包含send 函数的对象,但在您的模拟status: jest.fn() 中它将返回undefined

express 的 Response 对象是链式方法,这意味着函数会返回对象本身。

我们可以使用.mockReturnThis() 模拟相同的行为。

我还更新了您对中间件的期望:

.spec.ts

describe("Error handler middleware", () => {
  const error: HttpException = {
    name: "error",
    statusCode: 500,
    status: 1,
    message: "string",
    error: "string"
  };
  let mockRequest: Partial<Request>;
  let mockResponse: Partial<Response>;
  let nextFunction: NextFunction = jest.fn();

  beforeEach(() => {
    mockRequest = {};
    mockResponse = {
      status: jest.fn().mockReturnThis(), // This line
      send: jest.fn(), // also mocking for send function
    };
  });

  test("handle error when error includes statusCode", async () => {
    errorHandler(
      error as HttpException,
      mockRequest as Request,
      mockResponse as Response,
      nextFunction
    );

    expect(mockResponse.status).toHaveBeenCalledWith(500);
    expect(mockResponse.send).toHaveBeenCalledWith(error);
    expect(nextFunction).not.toHaveBeenCalled();
  });
});

【讨论】:

    猜你喜欢
    • 2022-10-06
    • 2021-04-14
    • 1970-01-01
    • 2021-08-15
    • 2020-05-17
    • 2019-10-10
    • 1970-01-01
    • 2017-02-16
    • 2021-08-04
    相关资源
    最近更新 更多