Shogun
Shogun

Reputation: 185

NestJs how to test response controller

I would like to test with jest the responses for my API.

this is method from controller

  @Post('send-banana')
  async sendBanana(
    @Body() request: BananaRequest,
    @Res() res: Response,
  ) {
    const responseCodeService = await this.bananaService.sendBanana(
      request,
    )

    res.status(responseCodeService).send({
      code: responseCodeService,
      message: HttpStatus[responseCodeService],
    })
  }

this is the test

  describe('Banana Controller', () => {
    fit('should return httpcode(201)', async () => {
      const result = await Promise['']

      const request = {
        origin: 'dummy origin',
        receiver: 'dummy@dummy',
        data: {
          name: 'Elsa Pallo',
        },
      } as BananaRequest

      const response = jest.fn((resObj) => ({
        status: jest.fn((status) => ({
          res: { ...resObj, statusCode: status },
        })),
      }))

      jest
        .spyOn(bananaService, 'sendBanana')
        .mockImplementation(() => result)

      expect(
        await bananaController.sendBanana(request, response),
      ).toBe(result)
    })
  })

This is the error that I get

enter image description here

Can someone guide me how I can mock the response?

Upvotes: 3

Views: 2301

Answers (2)

David Berríos
David Berríos

Reputation: 64

You need mock the response as follows:

const statusResponseMock = {
  send: jest.fn((x) => x),
}

const responseMock = {
  status: jest.fn((x) => statusResponseMock),
  send: jest.fn((x) => x),
} as unknown as Response

Upvotes: 4

sezanzeb
sezanzeb

Reputation: 1129

In case anyone is using foo.pipe(res), I made this class to test it:

class ResponseMock extends Writable {
    private responseText = '';

    public _write(
        chunk: string,
        encoding: BufferEncoding,
        callback: (error?: Error | null) => void
    ): void {
        this.responseText += chunk;
        callback();
    }

    /**
     * Wait for the response to complete and return it
     */
    public async getResponse(): Promise<string> {
        return await new Promise<string>((resolve): void => {
            this.on('finish', (): void => {
                resolve(this.responseText);
            });
        });
    }
}

which can be used like

import { Response } from 'express';

const responseMock = new ResponseMock();

await controller.query(
    param1,
    param2,
    responseMock as unknown as Response
);

await expect(responseMock.getResponse()).resolves.toEqual('foo');

Upvotes: 0

Related Questions