简体   繁体   中英

Mocking Express Response with JEST

I am pretty new to the jest and typescript, I am trying to create a small unit test for a controller function in jest

import { Request, Response } from 'express';

const healthCheck = (_req: Request, _res: Response) => {
  const value = _req.params.name ?? 'World!';
  return _res.status(200).json({ message: `Hello ${value}` });
};

export default healthCheck;

The unit test i wrote for the above function is

import { Request, Response } from 'express';

import healthCheck from './health.controller';

describe('Health Controller', () => {
  it('healthCheck should send 200 on an optional path param', () => {
    const req = { params: {} } as Request;
    const res = {
      json: jest.fn(),
      status: jest.fn(),
    } as unknown as Response;

    healthCheck(req, res);

    expect(res.status).toHaveBeenCalledWith(200);
  });
});

I am getting an error

TypeError: Cannot read property 'json' of undefined
>  8 |   return _res.status(200).json({ message: `Hello ${value}` });

why i am getting the json of undefined, even if i mock the property?

Since you're calling res.status().json() , json should be a function on the return value of status() , rather than on res .

A popular library for this type of mocking is node-mocks-http , which gives you req and res objects to pass into handlers so you don't have to mock them yourself.

Your mocks need a bit tweaking:

const json = jest.fn();
const status = jest.fn(() => json); // chained
const res = {
  json: json,
  status: status,
} as unknown as Response;

As @hellitsjoe pointed out, Express chains the call.

_res.status(200).json({ message: `Hello ${value}` })

So your mocks need to return other mocks for everything to work.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM