typescript 如何使用Jest模拟Express Respons.setHeader函数?

ecfsfe2w  于 2023-06-24  发布在  TypeScript
关注(0)|答案(1)|浏览(115)

我创建了一个自定义Express中间件,检查请求内容类型是否为JSON。如果不是这种情况,服务器将返回415和一个自定义错误对象

import { Request, Response, NextFunction } from "express";

function enforceContentTypeApplicationJson() {
  return (request: Request, response: Response, next: NextFunction) => {
    if (!request.is("application/json")) {
      response.setHeader('Content-Type', 'application/json');
      response.statusCode = 415;

      const actualContentType = request.get("Content-Type") ?? "";
      const errorResult = {
        isSuccessful: false,
        error: `Expected Content-Type 'application/json' but got '${actualContentType}'.`,
      };

      response.json(errorResult);

      return;
    }

    next();
  };
}

我想使用Jest测试这个中间件。我的第一个测试是

it("responds with status code 415 if header 'Content-Type' is not 'application/json'.", () => {
    const contentType = "multipart/form-data";
    const mockRequest: Partial<Request> = {
      headers: {
        "Content-Type": contentType,
      },
      is: jest.fn().mockImplementation(() => false),
      get: jest.fn().mockImplementation(() => contentType),
    };
    const mockResponse: Partial<Response> = {
      json: jest.fn(),
      setHeader: jest.fn().mockImplementation(function (name, value) {
        (this as unknown as Response).setHeader(name, value);
      }),
    };

    const nextFunction: NextFunction = jest.fn();

    const expectedResponse = {
      isSuccessful: false,
      error: `Expected Content-Type 'application/json' but got '${contentType}'.`,
    };

    const middleware = enforceContentTypeApplicationJson();

    middleware(mockRequest as Request, mockResponse as Response, nextFunction);

    expect(mockResponse.statusCode).toBe(415);
    // expect(mockResponse.getHeader('Content-Type')).toBe('application/json');
    // expect(mockResponse.getHeaders?.()["Content-Type"]).toBe('application/json');
    // expect(mockResponse.getHeader?.("Content-Type")).toBe('application/json');
    expect(mockResponse.json).toBeCalledWith(expectedResponse);
  });

但是我正在处理mockResponse.setHeader,因为testrunner失败并返回错误
this.setHeader不是函数
如何模拟Response类型的setHeader函数?我想提供一个模拟实现,因为稍后我还想为getHeader函数提供一个模拟实现,以便对响应内容类型进行Assert。

t9aqgxwy

t9aqgxwy1#

箭头函数没有自己的this绑定。我看不出有什么理由像那样模拟mockResponse.setHeader的实现。mockResponse.setHeader = jest.fn()就足够了,就像mockResponse.json()方法一样。

    • 更新**

我看不出有任何理由存储头文件并在以后获取它们以进行Assert。mockResponse对象是一个模拟对象,而不是真正的响应对象,不需要在mockResponse中存储头。
你可以这样做:

mockResponse.setHeader.toHaveBeenCalledWith('Content-Type', 'application/json')

相关问题