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?
CodePudding user response:
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.
CodePudding user response:
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.