Skip to main content
Handbook/Test/Chapter 72 · Test Data

Fake Data and Fake Services

Share

Share this page

Pass it to someone who needs it.

Key takeaway: Feed tests fake data, not the real thing

You have tests now, but a test needs something to run on, and some of your code reaches out to the real world: a payment provider, an email sender, another API. A test must never charge a real card, send a real email, or depend on data that changes underneath it. This chapter gets you controlled test data and safe stand-ins for those outside services.

8.3.1Tests need their own data

A test can only check "did I get the right answer" if it knows the answer in advance. That means predictable, controlled input, never your real or production data, which changes the moment a user edits something.

Prepared test data like this is a fixture: a fixed, known record your test runs against. Your agent writes these; here is the shape:

export const testUser = { id: "u_1", email: "[email protected]", plan: "free", };

The test uses testUser and knows exactly what to expect, every run, forever.

8.3.2Make data with a factory, not by hand

Writing each fixture by hand gets tedious fast, and one field changing in your data model breaks every one you typed out. When you need many records, or just realistic-looking ones, use a factory: a small function that builds fake data on demand.

A library like Faker fills in believable names, emails, and dates for you:

import { faker } from "@faker-js/faker"; export const makeUser = (over = {}) => ({ id: faker.string.uuid(), email: faker.internet.email(), ...over, });

Call makeUser() for a random one, or makeUser({ plan: "pro" }) to pin the one field a test cares about.

8.3.3Never call the real service in a test

Your code calls out to services you do not own: a card gets charged, an email gets sent, another API answers. In a test, none of that can happen. You cannot spend real money or send a real email a thousand times a day.

So you swap the real service for a mock: a stand-in that returns a canned response instead of doing the real thing. Tests stay fast, and they never touch the outside world.

In a test, calls to the outside world hit a mock that returns a canned answer, never the real service.

For code that talks to an API over HTTP, Mock Service Worker intercepts the request and hands back whatever you tell it:

http.post("https://api.stripe.com/v1/charges", () => HttpResponse.json({ id: "ch_test", status: "succeeded" }) );

The code under test thinks it charged a card. Nothing left your machine.

8.3.4Reset between tests, so they don't leak

A test that leaves data behind poisons the next one. If test A creates a user and test B counts users, B passes only because A ran first, and the day you run B alone, it fails for no reason you can see.

So every test starts from a clean slate. Reset the test database and any shared state before each one runs, so no test can depend on the leftovers of another. Your agent wires this into the test setup once.

Rule of thumb: any test must pass on its own, in any order. If it only passes after another test runs, something is leaking, reset it.

This prompt sets up test data and safe fakes for your stack:

Ready prompt
Act as a senior engineer setting up test data for my app. Do three things. First, add fixtures and factories: fixed records for known cases, a factory (Faker or my stack's equivalent) for realistic data on demand. Second, mock every external service so no test touches the real one: payments, email, any outside API. Return canned responses instead. Third, reset the test database and shared state before each test, so tests never depend on each other and pass in any order. Report what you faked and what you reset. My app and stack:

Do this now: paste the prompt, name the outside service your app calls first, and let your agent replace it with a mock before another test ever risks the real thing.

Mahmoud Zalt

Mahmoud Zalt

Software engineer, 16+ yrs · built Sistava.com in 3 months, idea to production, using these methods

Resources
Contribute
Donate

Support my work

A small tip keeps the free work coming.

© 2026 Mahmoud Zalt. Free to read, not to republish.
Copyright & license