JSON Test Data Strategies
1. Inline JSON in Tests
For small, focused tests, define JSON directly in the test file:
1import { describe, it, expect } from 'vitest';2import { transformUser } from '../utils/transform';34describe('transformUser', () => {5 it('extracts display name and role', () => {6 const apiResponse = {7 id: 42,8 first_name: 'Alice',9 last_name: 'Chen',10 role_id: 1,11 role_name: 'admin',12 created_at: '2026-01-15T10:00:00Z',13 };1415 const result = transformUser(apiResponse);1617 expect(result).toEqual({18 id: 42,19 displayName: 'Alice Chen',20 role: 'admin',21 });22 });23});Tip
toEqual() for deep equality on JSON-like objects. Use toMatchObject() when you only care about a subset of fields.2. Fixture Files
When test data is large or shared, extract it to JSON files:
1src/2 __fixtures__/3 users/4 admin.json5 regular-user.json6 api-response-list.json7 products/8 single-product.json9 catalog.json10 components/11 UserCard.test.tsx1{2 "id": 42,3 "name": "Alice Chen",4 "email": "[email protected]",5 "role": "admin",6 "permissions": ["read", "write", "delete"],7 "profile": {8 "avatar": "https://example.com/alice.jpg",9 "bio": "Senior developer"10 }11}1import adminUser from '../__fixtures__/users/admin.json';2import regularUser from '../__fixtures__/users/regular-user.json';34describe('UserCard', () => {5 it('shows admin badge for admin users', () => {6 render(<UserCard user={adminUser} />);7 expect(screen.getByText('Admin')).toBeInTheDocument();8 });910 it('hides admin badge for regular users', () => {11 render(<UserCard user={regularUser} />);12 expect(screen.queryByText('Admin')).not.toBeInTheDocument();13 });14});3. Factory Functions
Factories generate test data with defaults, letting you override only the fields relevant to each test:
1interface User {2 id: number;3 name: string;4 email: string;5 role: 'admin' | 'editor' | 'viewer';6 active: boolean;7 createdAt: string;8}910let nextId = 1;1112export function createUser(overrides: Partial<User> = {}): User {13 return {14 id: nextId++,15 name: 'Test User',16 email: `user-${nextId}@test.com`,17 role: 'viewer',18 active: true,19 createdAt: '2026-01-01T00:00:00Z',20 ...overrides,21 };22}1import { createUser } from '../factories/user';23describe('access control', () => {4 it('grants delete permission to admins', () => {5 const admin = createUser({ role: 'admin' });6 expect(canDelete(admin)).toBe(true);7 });89 it('denies delete to viewers', () => {10 const viewer = createUser({ role: 'viewer' });11 expect(canDelete(viewer)).toBe(false);12 });1314 it('ignores inactive users', () => {15 const inactive = createUser({ role: 'admin', active: false });16 expect(canDelete(inactive)).toBe(false);17 });18});Important
4. Snapshot Testing
Snapshot tests serialize output and compare it against a saved reference:
1import { transformApiResponse } from '../utils/transform';2import rawResponse from '../__fixtures__/api-response.json';34describe('API response transformation', () => {5 it('matches saved snapshot', () => {6 const result = transformApiResponse(rawResponse);7 expect(result).toMatchSnapshot();8 });910 it('matches inline snapshot', () => {11 const result = transformApiResponse({ id: 1, name: 'Test' });12 expect(result).toMatchInlineSnapshot(`13 {14 "id": 1,15 "displayName": "Test",16 "slug": "test",17 }18 `);19 });20});When to Use Snapshots
| Use Snapshots For | Avoid Snapshots For |
|---|---|
| Serialized output (JSON, HTML) | Volatile data (timestamps, random IDs) |
| API response transformations | UI behavior (clicks, navigation) |
| Config generation | Large objects with many irrelevant fields |
| Regression detection | New feature development (snapshots don't define intent) |
Snapshot Best Practices
- ✓Review snapshot diffs in PRs — do not blindly update
- ✓Keep snapshots small and focused (use
toMatchObjectfor partial matches) - ✓Use inline snapshots for tiny outputs so reviewers see the expectation in the test file
- ✗Don't snapshot entire API responses — extract and test the fields that matter
- ✗Don't test implementation details — snapshot the public output
5. Mocking API Responses with MSW
MSW (Mock Service Worker) intercepts HTTP requests and returns mock JSON at the network level:
1import { http, HttpResponse } from 'msw';2import { setupServer } from 'msw/node';34const handlers = [5 http.get('/api/users', () => {6 return HttpResponse.json([7 { id: 1, name: 'Alice', role: 'admin' },8 { id: 2, name: 'Bob', role: 'viewer' },9 ]);10 }),1112 http.get('/api/users/:id', ({ params }) => {13 if (params.id === '999') {14 return HttpResponse.json(15 { error: 'User not found' },16 { status: 404 }17 );18 }19 return HttpResponse.json({ id: Number(params.id), name: 'Alice' });20 }),2122 http.post('/api/users', async ({ request }) => {23 const body = await request.json();24 return HttpResponse.json({ id: 3, ...body }, { status: 201 });25 }),26];2728export const server = setupServer(...handlers);1import { server } from './mocks/server';23beforeAll(() => server.listen());4afterEach(() => server.resetHandlers());5afterAll(() => server.close());67describe('UserList component', () => {8 it('renders users from API', async () => {9 render(<UserList />);10 expect(await screen.findByText('Alice')).toBeInTheDocument();11 expect(screen.getByText('Bob')).toBeInTheDocument();12 });1314 it('shows error state for failed requests', async () => {15 server.use(16 http.get('/api/users', () => {17 return HttpResponse.json({ error: 'Server error' }, { status: 500 });18 })19 );20 render(<UserList />);21 expect(await screen.findByText(/error/i)).toBeInTheDocument();22 });23});6. Contract Testing with JSON Schema
Validate that API responses match an expected structure using JSON Schema:
1import Ajv from 'ajv';2import userSchema from '../schemas/user.json';34const ajv = new Ajv();5const validate = ajv.compile(userSchema);67describe('User API contract', () => {8 it('response matches JSON Schema', async () => {9 const response = await fetch('/api/users/1');10 const data = await response.json();1112 const valid = validate(data);13 if (!valid) {14 console.error(validate.errors);15 }16 expect(valid).toBe(true);17 });18});Try It — Validate Test Fixture Data
Try It Yourself
A test fixture — experiment with adding or removing fields