如何使用Typescript模拟Express Request,Response和NextFunction对象

时间:2019-03-02 17:19:22

标签: typescript jestjs

这是我的中间件:

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模块,但还没有成功。我该如何嘲笑他们?

2 个答案:

答案 0 :(得分:5)

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

由于您的代码未使用reqres,因此您可以将空对象作为模拟传递,并告诉TypeScript使用as将模拟作为预期类型:

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

更新

如果要模拟RequestResponse上的其他属性,则只需将这些属性添加到模拟对象中即可。

您的模拟对象(可能)不会实现完整的RequestResponse接口,因此您可以使用Partial<Request>Partial<Response>之类的东西,或者只是告诉TypeScript您通过为模拟对象使用类型any"to opt-out of type-checking and let the values pass through compile-time checks"

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
});

答案 1 :(得分:0)

您可以使用 Typescript 中的 Utility Types。喜欢:

const middleware = middlewares.isLogged()

const req: Partial<Request> = {};
const res: Partial<Response> = {};
const next: NextFunction = jest.fn();

middleware(req, res, next);