How can I mock fetch function in Node.js by Jest?
Asked Answered
H

3

22

How can I mock fetch function in Node.js by Jest?

api.js

'use strict'
var fetch = require('node-fetch');

const makeRequest = async () => {
    const res = await fetch("http://httpbin.org/get");
    const resJson = await res.json();
    return resJson;
};

module.exports = makeRequest;

test.js

describe('fetch-mock test', () => {
    it('check fetch mock test', async () => {

        var makeRequest = require('../mock/makeRequest');

        // I want to mock here


         global.fetch = jest.fn().mockImplementationOnce(() => {
           return new Promise((resolve, reject) => {
            resolve({
                ok: true,
                status,
                json: () => {
                    return returnBody ? returnBody : {};
                },
               });
          });
        });

        makeRequest().then(function (data) {
            console.log('got data', data);
        }).catch((e) => {
            console.log(e.message)
        });

    });
});

I tried to use jest-fetch-mock, nock and jest.mock but failed.

Thanks.

Hidden answered 26/11, 2018 at 15:20 Comment(1)
Can you show how it failed with nock? What was the code/error message?Psychopathology
D
20

You can mock node-fetch using jest.mock. Then in your test set the actual mock response

import fetch from 'node-fetch'
jest.mock('node-fetch', ()=>jest.fn())

describe('fetch-mock test', () => {
    it('check fetch mock test', async () => {

        var makeRequest = require('../mock/makeRequest');


         const response = Promise.resolve({
                ok: true,
                status,
                json: () => {
                    return returnBody ? returnBody : {};
                },
               })
        fetch.mockImplementation(()=> response)
        await response
        makeRequest().then(function (data) {
            console.log('got data', data);
        }).catch((e) => {
            console.log(e.message)
        });

    });
});
Dandiprat answered 26/11, 2018 at 15:29 Comment(4)
Not sure why you'd care about mocking it and importing it in the test class... Why not mock it so that the target code the test is for that imports fetch, the test code needs to mock that.Rigmarole
fetch returns undefined in the code to be tested.Tortuosity
For me as well, fetch is undefined, I cannot call mockImplementation on it.Noctilucent
Doesn't work with node-fetch 3.3.2 and ts-jest 29.1.1. The original fetch function is not mocked. It always returns the original fetch function, without mocked functions like mockResolvedValue. I tried adding jest.mock before and after the importCoke
P
12
import fetch, { Response } from 'node-fetch';

jest.mock('node-fetch');

describe('fetch-mock test', () => {
    const mockFetch = fetch as jest.MockedFunction<typeof fetch>;

    it('check fetch mock test', async () => {
      const json = jest.fn() as jest.MockedFunction<any>;
      json.mockResolvedValue({ status: 200}); //just sample expected json return value
      mockFetch.mockResolvedValue({ ok: true, json } as Response); //just sample expected fetch response
      await makeRequest();
      expect(json.mock.calls.length).toBe(1);
    })
})
Palacios answered 14/7, 2021 at 13:55 Comment(1)
Using jest 27, still encountering the same issue where I cannot call any methods on 'mockFetch' (trying to call 'mockImplementation' in my case)Novelist
B
-2

I've found that the easiest way to mock ECMAScript modules in Jest is by using jest.unstable_mockModule.

Example:

jest.unstable_mockModule("node-fetch", () => ({
  default: (url) => {
    if (url.includes("/groups/")) {
      return {
        ok: true,
        json: () => ({
          id: dummyGuid,
          name: "dummyStringForName",
          embedUrl: "https://example.com",
          datasetId: dummyGuid,
        }),
      }
    }
    if (url.endsWith("/GenerateToken")) {
      return {
        ok: true,
        json: () => ({
          token: "dummyStringForToken",
        }),
      }
    }
  },
}))
Barnabas answered 16/3, 2023 at 10:16 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.