Marian Bazalik
Marian Bazalik

Reputation: 1395

How to mock fetch Response object

I trying to mock fetch response with ts-jest, and I am running into typescript error

import { mocked } from 'ts-jest/utils';
import fetch from 'node-fetch';

import { getInstallationAccessToken } from './index';

const mockedFetch = mocked(fetch, true);

describe('getInstallationAccessToken', () => {
  const TODAY = new Date();
  const TOMORROW = new Date();
  TOMORROW.setDate(TODAY.getDate() + 1);

  beforeEach(() => {
    mockedFetch.mockResolvedValue({
      status: 200,
      json: async () => ({
        token: 'MOCKED_GITHUB_INSTALLATION_ACCESS_TOKEN',
        expires_at: TOMORROW.toISOString()
      })
    });
    jest.clearAllMocks();
  });

  test('generates github app jwt token', async () => {
    await getInstallationAccessToken();
    expect(mockedJwt.sign).toBeCalledTimes(1);
  });
})

With this example, I am getting the following error:

Argument of type '{ status: number; json: () => Promise<{ token: string; expires_at: string; }>; }' is not assignable to parameter of type 'Promise<Response> | PromiseLike<Promise<Response>>'.
  Object literal may only specify known properties, and 'status' does not exist in type 'Promise<Response> | PromiseLike<Promise<Response>>'.ts(2345)

So I attempted to construct a proper Response object:

    const response = new Response(JSON.stringify({
      token: 'MOCKED_GITHUB_INSTALLATION_ACCESS_TOKEN',
      expires_at: TOMORROW.toISOString()
    }),  { status: 200 })


    mockedFetch.mockReturnValue(Promise.resolve(response));

However now, the .json method is not defined on the response object

TypeError: response.json is not a function

      56 |     });
      57 |
    > 58 |     const json = await response.json();
         |                                 ^
      59 |
      60 |     if (response.status >= 300) {
      61 |       throw new Error(

Any ideas on how to get around this?

Upvotes: 6

Views: 18685

Answers (1)

tmhao2005
tmhao2005

Reputation: 17504

I think you can again to try with your 1st mock and cast your mocked object as Response would work as following:


import fetch, { Response } from 'node-fetch';


mockedFetch.mockResolvedValue({
  status: 200,
  json: async () => ({
    token: 'MOCKED_GITHUB_INSTALLATION_ACCESS_TOKEN',
    expires_at: TOMORROW.toISOString()
  })
} as Response); // cast to Response type since we just mock what we need to

Upvotes: 8

Related Questions