Stop 08 · API TestingTopics · 9/9

Mocking & Stubbing APIs

Part of the QA Testing Roadmap

In short

How do you test the 'payment service down' screen when payments never go down in QA? You fake the API. Mocks let you create any response on demand.

Simulating an API's responses without calling the real backend — useful for testing in isolation, testing error scenarios that are hard to trigger for real, and testing before a dependent service is even built.

The purple blob rehearses on a small stage opposite a flat cardboard cut-out of an actor.

Think of it like this

Rehearsing with a cardboard cut-out

The lead actor is shooting in another city, but the play rehearses anyway. A cardboard cut-out stands in, and someone reads the lines. A mock API is that cut-out: it gives the replies you script, so the rest of the show can practise.

Watch it happen

Faking an outage for one test

Test
Web app
Mock API

route /api/orders -> 503

1/5Before the page loads, the test tells the mock to answer orders calls with 503.

The big ideas

What you need to know

Stub vs mock

A stub returns canned answers. A mock also checks it was called the right way. People often mix the terms.

Hard cases on demand

Timeouts, 500s, empty lists, huge lists. Fake them in seconds instead of waiting for them.

Test in isolation

Test your app before a partner's API is ready, or when their sandbox is down.

Mocks can lie

If the real API changes, your mock won't. Pair mocks with contract tests.

See it in code

Walk through the code

ts
1import { test, expect } from "@playwright/test";2 3test("orders page shows an error when the API is down", async ({ page }) => {4  await page.route("**/api/orders", (route) =>5    route.fulfill({ status: 503, body: "Service Unavailable" })6  );7 8  await page.goto("https://qa.your-app.test/orders");9  await expect(page.getByText("Something went wrong")).toBeVisible();10});

1/3Any request matching the pattern gets this fake response instead of a real one.

Playwright intercepts the app's API call and returns a fake 503. Cypress does the same with cy.intercept.

Save yourself the pain

Common mistakes

Oops

Mocking everything, so no test ever touches the real API.

Do this instead

Use mocks for hard-to-reach cases. Keep some tests running against the real integration too.

Oops

Hand-writing mock responses that don't match the real API's shape.

Do this instead

Copy real responses or generate mocks from the API's OpenAPI spec.

Your mission

Block and fake responses

~30 min

Quick check

Why should mocks be paired with contract tests?

Go deeper

  1. 1Set up a basic API mock returning a predefined response for a sample test.
  2. 2Learn why mocking is especially useful for testing error scenarios (like a 500 response) reliably.
  3. 3Understand the trade-off: mocks test your handling logic, not the real integration.

More topics at this stop

Stuck on this topic? Ask an Insider

Get 1:1 guidance from people who've walked this exact path — on the InsideEdge app.

Download
InsideEdge