首页 > 解决方案 > 如何使用 Typescript 模拟 Express Request、Response 和 NextFunction 对象

问题描述

这是我的中间件:

export const isLogged = () => (req: Request, res: Response, next: NextFunction) => next();

我正在尝试创建一个单元测试,但我无法使用正确的类型进行模拟:

const middleware = middlewares.isLogged()

middleware(
  jest.fn<Request>(), // Expected 0-2 type argument but got 1
  jest.fn<Response>(),
  jest.fn<NextFunction>(),
);

这不起作用,我尝试过express模拟模块等,但还没有让它工作。我怎么能嘲笑他们?

标签: typescriptjestjs

解决方案


前两个参数是一个Request对象和一个Response对象。

由于您的代码不使用req,或者res您可以将空对象作为模拟传递并告诉 TypeScript 将模拟视为预期类型,使用as

it('should call next', () => {
  const next = jest.fn();
  middleware(
    {} as Request,
    {} as Response,
    next,
  );
  expect(next).toHaveBeenCalled();  // SUCCESS
});

更新

如果您想模拟其他属性,Request或者Response然后您可以简单地将它们添加到您的模拟对象中。

您的模拟对象(可能)不会实现完整的RequestorResponse接口,因此您可以使用类似Partial<Request>or的东西Partial<Response>,或者只是告诉 TypeScript 您想要“选择退出类型检查并让值通过编译时检查”通过使用模拟对象的类型any

it('should call next', () => {
  const req: any = {
    get: jest.fn((name) => {
      if (name === 'content-type') return 'text/plain';
    })
  };
  const res: any = {
    send: jest.fn()
  }
  const next = jest.fn();
  middleware(
    req,
    res,
    next,
  );
  expect(next).toHaveBeenCalled();  // SUCCESS
});

推荐阅读