jefflau / jest-fetch-mock

Jest mock for fetch
MIT License
883 stars 116 forks source link

Mock a cross-fetch ponyfill #122

Open nikolakov opened 5 years ago

nikolakov commented 5 years ago

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?

ctaylo21 commented 4 years ago

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!

derolf commented 2 years ago
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 }));
}
zainfathoni commented 2 years ago

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

landabaso commented 2 years ago

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);
  });
});