R

React Handbook

Clean • Professional

React Mocking : API Calls, Modules, and Functions

2 minute

React Mocking

In React applications, components often depend on APIs or external modules. During testing, you don’t want to make real network requests or rely on actual modules. This is where mocking comes in handy. Mocking allows you to simulate external dependencies and test your components in isolation.

Why Mocking is Important

  1. Isolation – Test components without depending on external APIs
  2. Speed – Avoid real HTTP requests to make tests faster
  3. Reliability – Prevent flaky tests caused by network issues
  4. Control – Simulate different scenarios like success, failure, or edge cases

Mocking API Calls

Suppose you have a component that fetches user data:

// UserProfile.jsx
import React, { useEffect, useState } from "react";

function UserProfile({ userId }) {
  const [user, setUser] = useState(null);

  useEffect(() => {
    fetch(`https://jsonplaceholder.typicode.com/users/${userId}`)
      .then(res => res.json())
      .then(data => setUser(data));
  }, [userId]);

  if (!user) return <p>Loading...</p>;

  return <div>{user.name}</div>;
}

export default UserProfile;

Mocking Fetch in Jest

// UserProfile.test.jsx
import React from "react";
import { render, screen, waitFor } from "@testing-library/react";
import UserProfile from "./UserProfile";

// Mock the global fetch function
global.fetch = jest.fn(() =>
  Promise.resolve({
    json: () => Promise.resolve({ name: "John Doe" }),
  })
);

test("renders user name after API call", async () => {
  render(<UserProfile userId={1} />);

  // Wait for the user name to appear
  const userName = await waitFor(() => screen.getByText("John Doe"));

  expect(userName).toBeInTheDocument();
  expect(fetch).toHaveBeenCalledTimes(1);
  expect(fetch).toHaveBeenCalledWith(
    "<https://jsonplaceholder.typicode.com/users/1>"
  );
});
  • jest.fn() → creates a mock function
  • Promise.resolve() → simulates async API response
  • waitFor() → waits for async updates in the component

Mocking Modules

Sometimes, you want to mock entire modules, such as utility functions.

// utils.js
export const calculateDiscount = (price) => price * 0.9;
// Component.jsx
import React from "react";
import { calculateDiscount } from "./utils";

function Price({ amount }) {
  return <p>Discounted Price: {calculateDiscount(amount)}</p>;
}

export default Price;

Mock the module in tests

// Component.test.jsx
import React from "react";
import { render, screen } from "@testing-library/react";
import Price from "./Component";

// Mock the module
jest.mock("./utils", () => ({
  calculateDiscount: jest.fn(() => 50), // always return 50
}));

test("renders mocked discounted price", () => {
  render(<Price amount={100} />);
  expect(screen.getByText("Discounted Price: 50")).toBeInTheDocument();
});

Benefits:

  • Replace actual implementation
  • Control return values for testing different scenarios

Mocking Functions Passed as Props

When a parent passes functions to a child, you can mock them with Jest to verify interactions.

function Button({ onClick }) {
  return <button onClick={onClick}>Click Me</button>;
}

// Test
test("calls onClick handler when clicked", () => {
  const handleClick = jest.fn();
  render(<Button onClick={handleClick} />);

  screen.getByText("Click Me").click();
  expect(handleClick).toHaveBeenCalledTimes(1);
});
  • jest.fn() creates a spy function
  • toHaveBeenCalledTimes ensures the function was triggered

Article 0 of 0