Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I mock with Typescript the Express Request, Response and NextFunction objects

This is my middlewares:

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

I'm trying to create a unit test but I'm unable to mock with the correct types:

const middleware = middlewares.isLogged()

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

This is not working, I've tried mocking the express module and such but haven't gotten it to work. How can I mock them?

like image 230
Christopher Francisco Avatar asked Mar 02 '19 17:03

Christopher Francisco


People also ask

How do you mock a function?

There are two ways to mock functions: Either by creating a mock function to use in test code, or writing a manual mock to override a module dependency.


2 Answers

The first two arguments are a Request object and a Response object.

Since your code doesn't use req or res you can just pass empty objects as mocks and tell TypeScript to treat the mocks as the expected types using as:

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

Update

If you want to mock additional properties on Request or Response then you can simply add these to your mock object.

Your mock object will (probably) not implement the full Request or Response interface so you can either use something like Partial<Request> or Partial<Response>, or simply tell TypeScript you want "to opt-out of type-checking and let the values pass through compile-time checks" by using the type any for the mock objects:

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
});
like image 159
Brian Adams Avatar answered Oct 19 '22 19:10

Brian Adams


You can use Utility Types from Typescript. Like:

const middleware = middlewares.isLogged()

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

middleware(req, res, next);
like image 1
Ismayil Niftaliyev Avatar answered Oct 19 '22 20:10

Ismayil Niftaliyev