📘 ReactJS

Mocking API Calls

API mocking lets frontend tests reproduce success, validation errors, authorization failures, delays, and server failures without depending on a live backend. A good mock behaves like the real API contract rather than simply returning whatever makes the test pass.

S

Site Administrator

📅 Sep 28, 2026 🕒 2 min read 👁 23 views
☆ Save 𝕏 in f ✆
Mocking API Calls

API mocking lets frontend tests reproduce success, validation errors, authorization failures, delays, and server failures without depending on a live backend. A good mock behaves like the real API contract rather than simply returning whatever makes the test pass.

Why API mocking is needed

Real APIs make tests slow, flaky, environment-dependent, and difficult to control. Mocking lets a test deliberately reproduce situations that are difficult to trigger on demand.

Mock fetch

global.fetch = vi.fn();

fetch.mockResolvedValue({
  ok: true,
  json: async () => ({
    items: [{ id: 1, name: "Laptop" }]
  })
});

Mock Axios

vi.mock("axios");

axios.get.mockResolvedValue({
  data: {
    items: [{ id: 1, name: "Laptop" }]
  }
});

Mock success and failure

api.get
  .mockResolvedValueOnce({
    data: { items: [] }
  })
  .mockRejectedValueOnce(
    new Error("Network error")
  );

MSW approach

Mock Service Worker is useful for larger test suites because it mocks requests at the network boundary. The application still performs normal HTTP requests, while the test server controls the response.

http.get("/api/products", () => {
  return HttpResponse.json({
    items: [
      { id: 1, name: "Laptop" }
    ]
  });
});

Testing 401

server.use(
  http.get("/api/profile", () => {
    return new HttpResponse(null, {
      status: 401
    });
  })
);

render(<Profile />);

expect(
  await screen.findByText(/sign in again/i)
).toBeInTheDocument();

Testing 500

server.use(
  http.get("/api/products", () => {
    return new HttpResponse(null, {
      status: 500
    });
  })
);

expect(
  await screen.findByText(/unable to load/i)
).toBeInTheDocument();

Testing slow API

http.get("/api/products", async () => {
  await delay(1000);

  return HttpResponse.json({
    items: []
  });
});

This allows the test to verify loading indicators and disabled buttons.

Mock contract example

GET /api/products

Success:
200
{
  "items": [...]
}

Unauthorized:
401

Server failure:
500

Output

Scenario: successful API
UI: Laptop displayed

Scenario: 401
UI: Please sign in again

Scenario: 500
UI: Unable to load products

Scenario: slow response
UI: Loading products...

Common mistakes

  • Mocking the function instead of the HTTP boundary for every integration test.
  • Returning unrealistic data.
  • Not testing failure responses.
  • Allowing tests to leak mock state into other tests.
  • Testing only 200 responses.

Interview questions

  • Why mock APIs?
  • Fetch mock vs MSW?
  • How would you test 401 and 500?
  • How do you test a loading state caused by a slow API?

Comments & Ratings (0)

Log in or create a student account to comment and rate this article.

Be the first to comment on this article.

Never miss a new post 📬

Get an email whenever a new article, project, cheatsheet or video drops.

✅

ℹ️