Home > Enterprise >  how to mock a nested response object parameter in jest?
how to mock a nested response object parameter in jest?

Time:06-30

I am writing a unit tests for this specific endpoint but I can't mock the Response Parameter, it is throwing an error in the .json part whenever it tries to access it.

async createTenant(@Body() clientDto: ClientDto, @Res() res: any)

This is where I access it inside the controller. It is throwing an error inside the .json function, how do I mock this property?

return res.status(HttpStatus.BAD_REQUEST).json({
    message: 'Client already exists.',
});

I already tried something like this:

const jsonFn = jest.fn().mockImplementation().mockResolvedValueOnce({ message: 'something' });
const res = { status: jest.fn().mockResolvedValueOnce({ json: jsonFn })};

It is now working for the .status part but for the .json it is still throwing an error. Any ideas that might help?

CodePudding user response:

You should try using a library to mock the Request and Response objects, the best one I have found so far is @jest-mock/express.

You can use it like this:

import { getMockRes } from '@jest-mock/express'


const { res } = getMockRes();

You can similarly mock Request as well, the docs are very clear on the usage.

CodePudding user response:

There are many ways we can reason about this.

For example, imagine the following controller:

import { Body, Controller, Get, HttpStatus, Res } from "@nestjs/common";

export class TestDto {
  hello?: string;
}

@Controller()
export class TestController {
  @Get()
  public async create(
    @Body() testDto: TestDto,
    @Res() res: any
  ): Promise<string> {
    res
      .status(HttpStatus.BAD_REQUEST)
      .json({ message: "i'm testting a bad request" });

    return testDto.hello ?? "hello is missing";
  }
}

We can test the calls made to status and json:

describe("TestController", () => {
  let controller: TestController;

  const mockJson = jest.fn().mockImplementation(() => null),
    mockStatus = jest.fn().mockImplementation(() => ({ json: mockJson })),
    mockResponse = {
      status: mockStatus,
    },
    mockDto = { hello: "world" };

  beforeEach(() => {
    jest.clearAllMocks();
  });

  beforeEach(async () => {
    const module = await Test.createTestingModule({
      providers: [TestController],
    }).compile();

    controller = module.get(TestController);
  });

  beforeEach(async () => {
    await controller.create(mockDto, mockResponse);
  });

  it("checks call to status", () => {
    expect(mockStatus).toHaveBeenCalledWith(HttpStatus.BAD_REQUEST);
  });

  it("checks call to json", () => {
    expect(mockJson).toHaveBeenCalledWith({
      message: "i'm testting a bad request",
    });
  });
});
  • Related