Codementor Events

Complete Guide to Mocking Fetch in Jest

Published Oct 25, 2024

If you've ever tried testing API calls in a Jest environment, you might've hit a wall with fetch not working.

Jest runs in a Node-like setup, which—unlike browsers—doesn't have fetch built-in.

So yeah, no fetch out of the box!

But don’t worry, it’s a quick fix, and there are some solid workarounds to get you up and running with your API tests in no time.
Let’s dive into why this happens and the easiest ways to fix it.

you can use one of the following options:

Install and mock fetch:

Use libraries like whatwg-fetch or node-fetch to add fetch support

npm install whatwg-fetch --save-dev

Then in your test setup file (like jest.setup.js), import it:

import 'whatwg-fetch';

jest-fetch-mock

If you need more control, jest-fetch-mock allows you to mock fetch calls and define custom responses.

npm install jest-fetch-mock --save-dev

Then in your Jest setup file:

import fetchMock from 'jest-fetch-mock';
fetchMock.enableMocks();

How to Mock Fetch in Jest

Here's a step-by-step guide to properly mocking fetch:

Basic Setup

describe("API Tests", () => {
  beforeEach(() => {
    global.fetch = jest.fn();
  });

  afterEach(() => {
    jest.clearAllMocks();
  });
});

Mocking Successful Responses

it("handles successful API calls", async () => {
  // Setup mock response
  const mockData = { success: true, data: "test" };
  global.fetch = jest.fn().mockResolvedValue({
    ok: true,
    json: () => Promise.resolve(mockData)
  });

  // Make API call
  const response = await fetch('/api/data');
  const data = await response.json();

  // Verify results
  expect(data).toEqual(mockData);
});

Handling Error Cases

it("handles API errors", async () => {
  // Mock network error
  global.fetch = jest.fn().mockRejectedValue(
    new Error("Network error")
  );

  // Verify error handling
  await expect(fetch('/api/data'))
    .rejects
    .toThrow("Network error");
});

Best Practices

Create Helper Functions

// Helper for common mock responses
const createMockResponse = (data, options = {}) => ({
  ok: true,
  status: 200,
  json: () => Promise.resolve(data),
  ...options
});

// Usage
it("uses helper function", async () => {
  global.fetch = jest.fn().mockResolvedValue(
    createMockResponse({ data: "test" })
  );
});

Test Different Scenarios

describe("API Scenarios", () => {
  it("handles success case", async () => {
    global.fetch = jest.fn().mockResolvedValue(
      createMockResponse({ data: "success" })
    );
  });

  it("handles 404 error", async () => {
    global.fetch = jest.fn().mockResolvedValue({
      ok: false,
      status: 404,
      json: () => Promise.resolve({ error: "Not found" })
    });
  });

  it("handles network timeout", async () => {
    global.fetch = jest.fn().mockImplementation(() => 
      new Promise((_, reject) => 
        setTimeout(() => reject(new Error("Timeout")), 100)
      )
    );
  });
});

Conclusion

Mocking fetch in Jest is essential for writing reliable, fast, and maintainable tests.

Remember:

  • Always mock fetch in tests
  • Clean up after each test
  • Test both success and error cases
  • Use helper functions for common patterns
  • Keep your tests focused and isolated

This approach will help you write better, more maintainable tests that you can trust.

Discover and read more posts from Nabil CHIHEB
get started