# Mocking strategy documented

- **Pattern:** `ab-002147` (`code-quality-essentials.testing.mocking-strategy`)
- **Severity:** low
- **Lifecycle:** active
- **Last modified:** 2026-04-18
- **Canonical URL:** https://auditbuffet.com/patterns/ab-002147
- **License:** CC-BY-4.0 — attribute to AuditBuffet Pattern Catalog (https://auditbuffet.com/patterns/ab-002147)

## Why it matters

Unit tests that call real external services — databases, APIs, email providers — are not unit tests: they are slow, flaky, and environment-dependent. ISO 25010:2011 §6.5.5 requires that tests produce deterministic results. Without consistent mocking, a failing test might be a real bug, a network blip, a rate limit hit, or a service outage — and distinguishing between them wastes engineering time. Real API calls in tests also risk leaking test data to production systems or incurring costs from development runs.

## Severity rationale

Low because unmocked external calls make tests non-deterministic and environment-dependent, which erodes confidence in the test suite and often leads to tests being ignored or disabled.

## Remediation

Adopt a consistent mocking strategy. For HTTP calls, `msw` (Mock Service Worker) intercepts at the network layer and works with any fetch-based code:

```typescript
// tests/mocks/handlers.ts
import { http, HttpResponse } from 'msw'

export const handlers = [
  http.get('/api/users/:id', ({ params }) => {
    return HttpResponse.json({ id: params.id, name: 'Test User' })
  }),
  http.post('/api/users', () => {
    return HttpResponse.json({ id: 'new-id' }, { status: 201 })
  }),
]
```

For module-level mocking in Vitest:
```typescript
vi.mock('@/lib/email', () => ({
  sendEmail: vi.fn().mockResolvedValue({ success: true }),
}))
```

Store reusable fixture data in `tests/fixtures/` as typed constants or JSON files.

## Detection

- **ID:** `mocking-strategy`
- **Severity:** `low`
- **What to look for:** Check test files for consistent use of mocking patterns to isolate the unit under test. Look for `vi.mock()` (Vitest), `jest.mock()` (Jest), or manual mock files in `__mocks__/` directories. External service dependencies (API calls, database access, email sending, third-party SDKs) should be mocked in unit tests — not called for real. Also check for fixture data files: JSON files or TypeScript constants in `__fixtures__/`, `tests/fixtures/`, or similar directories that provide consistent test data. If tests appear to call real external services (no mocking setup, no HTTP interceptors like `msw`), flag this as a test isolation problem.
- **Pass criteria:** Enumerate all relevant code locations. Unit tests use `vi.mock`/`jest.mock` or similar to isolate external dependencies. Mock data fixtures are present and reusable. External HTTP calls in tests use MSW or a fetch mock with at least 1 verified location.
- **Fail criteria:** Unit tests appear to call real external services or APIs without mocking. No fixture data. Mocking is entirely absent.
- **Skip (N/A) when:** No test files exist.
- **Detail on fail:** `"Unit tests appear to call real APIs without mocking; no mock files or fixtures found in test directories"`
- **Remediation:** Adopt a consistent mocking strategy. For HTTP calls, `msw` (Mock Service Worker) is the gold standard:

  ```typescript
  // tests/mocks/handlers.ts
  import { http, HttpResponse } from 'msw'

  export const handlers = [
    http.get('/api/users/:id', ({ params }) => {
      return HttpResponse.json({ id: params.id, name: 'Test User' })
    }),
    http.post('/api/users', () => {
      return HttpResponse.json({ id: 'new-id' }, { status: 201 })
    }),
  ]
  ```

  For module mocking in Vitest:
  ```typescript
  vi.mock('@/lib/email', () => ({
    sendEmail: vi.fn().mockResolvedValue({ success: true }),
  }))
  ```

---

## External references

- iso-25010 maintainability.testability

Taxons: code-quality

HTML version: https://auditbuffet.com/patterns/ab-002147
