jest-fetch-mock icon indicating copy to clipboard operation
jest-fetch-mock copied to clipboard

Mock a cross-fetch ponyfill

Open nikolakov opened this issue 6 years ago • 4 comments

I'm currently testing a project, which uses cross-fetch ponyfills in the files (i.e. import fetch from "cross-fetch"). this comment in #82 suggests just using cross-fetch as polyfill instead of ponyfill, but that's not an option in my case. Is it possible to mock the fetch imported as a module?

nikolakov avatar Jul 04 '19 16:07 nikolakov

I use unfetch and I was able to get everything working with this setup file:

import { GlobalWithFetchMock } from 'jest-fetch-mock';

const customGlobal = global as GlobalWithFetchMock;
customGlobal.fetch = require('jest-fetch-mock');
customGlobal.fetchMock = customGlobal.fetch;

jest.setMock('unfetch', fetch); // Use this to mock your ponyfilled fetch module

Hope this helps!

ctaylo21 avatar Oct 15 '19 15:10 ctaylo21

export const mockedFetch = jest.fn() as jest.MockedFunction<typeof fetch>;

jest.mock("cross-fetch", () => ({
  ...jest.requireActual("cross-fetch"),
  __esModule: true,
  fetch: mockedFetch,
  default: mockedFetch,
}));

// must come AFTER mocking!
import fetch, { Response } from "cross-fetch";

export function mockFetchOnce(status: number, json: unknown): void {
  mockedFetch.mockResolvedValueOnce(new Response(JSON.stringify(json), { status }));
}

derolf avatar Sep 06 '21 12:09 derolf

I managed to do it by simply doing this in the setup test file:

import fetchMock from "jest-fetch-mock";

jest.setMock("cross-fetch", fetchMock);

You can look at the complete PR where I introduced jest-fetch-mock into our open source project over here: kawalcovid19/wargabantuwarga.com#788

zainfathoni avatar Sep 06 '21 17:09 zainfathoni

This is the recommended way according to jest documentation:

jest.mock('cross-fetch', () => {
  const fetchMock = require('jest-fetch-mock');
  // Require the original module to not be mocked...
  const originalFetch = jest.requireActual('cross-fetch');
  return {
    __esModule: true,
    ...originalFetch,
    default: fetchMock
  };
});

import fetch from 'cross-fetch';
//Do not mock unless we explicitly request it.
fetch.dontMock();

describe('fetch', () => {
  test('fetch', async () => {
    fetch.mockResponse(JSON.stringify({ hello: 'world' }));
    //Activate the mock
    //This will not result into a query to google:
    fetch.doMock();
    expect(await (await fetch('https://www.google.com')).json()).toEqual({
      hello: 'world'
    });
    //Turn off
    fetch.dontMock();
    //Now you can fetch() stuff and the mock won't be applied.
    //This will really query google.com:
    expect((await fetch('https://www.google.com')).status).toEqual(200);
  });
});

landabaso avatar Apr 22 '22 13:04 landabaso