API Mocking
debt(d7/e5/b5/t5)
Closest to 'only careful code review or runtime testing' (d7). The detection_hints confirm automated detection is 'no' — the code pattern is 'integration tests hitting real external APIs' which tools like wiremock, mockery, guzzle-mock, php-vcr don't automatically flag. You need careful code review or noticing flaky CI failures to realize tests are hitting real APIs instead of mocks. No static analysis tool catches missing mocks by default.
Closest to 'touches multiple files / significant refactor in one component' (e5). The quick_fix says 'Use WireMock or Mockery HTTP stubs' which sounds simple, but in practice retrofitting mocks into an existing test suite that hits real APIs requires creating mock response fixtures, setting up MockHandlers or mock servers, and updating multiple test files. It's not a one-line fix — it's a significant refactor across the test layer, though typically contained to one component (the test suite).
Closest to 'persistent productivity tax' (b5). Once you adopt API mocking, every test that touches external APIs needs maintained mock responses. The common_mistakes highlight 'outdated mock responses' and 'mock responses that don't match the actual API spec' — this is an ongoing tax. The applies_to scope covers web and cli contexts. Mock fixtures become a parallel maintenance burden alongside the real API integration, affecting multiple work streams whenever the external API contract changes.
Closest to 'notable trap (a documented gotcha most devs eventually learn)' (t5). The misconception field directly states the trap: developers assume 'mocking APIs means making HTTP calls to a local mock server' when in fact for unit tests, Guzzle MockHandler intercepts at the HTTP client level without any network connection. This is a genuine conceptual confusion between client-level mocking (unit tests) vs. mock servers (integration/frontend tests). It's a well-documented gotcha that most devs eventually learn, but it causes real confusion initially.
Also Known As
TL;DR
Explanation
API mocking tools: Prism — generates a mock server from an OpenAPI spec instantly, returning example responses. WireMock — record real API calls and replay them, or configure stub responses with delays and error simulation. Mockoon — desktop GUI for managing mock APIs. PHP unit tests: Guzzle MockHandler intercepts HTTP at the client level — no actual network connection made. Use cases: test error scenarios (429, 503, timeouts) that are hard to trigger with real APIs, CI without external service dependencies, and frontend development before the backend is ready.
Common Misconception
Why It Matters
Common Mistakes
- Real API calls in unit tests — slow, flaky, require network, create production test data
- Mock responses that don't match the actual API spec — tests pass but integration fails
- Not testing error scenarios — real APIs fail; mocks must simulate 429, 503, network timeouts
- Outdated mock responses — mocks must be updated when the real API contract changes
Avoid When
- Avoid mocking as a substitute for contract or integration tests — mocks can drift from the real API silently.
- Do not mock at the HTTP level in integration tests that are specifically meant to verify end-to-end behaviour.
- Avoid over-specifying mock responses — brittle mocks that encode every response field break when the API evolves.
When To Use
- Unit testing code that calls external HTTP APIs — mocks remove network dependency and make tests deterministic.
- Developing a consumer before the provider API is ready — a mock server lets both teams work in parallel.
- Testing error and edge-case responses (timeouts, 429, 503) that are hard to trigger against a real service.
Code Examples
// Real HTTP calls in unit test — slow and fragile:
public function testSendConfirmationEmail(): void {
$mailer = new SendGridMailer(API_KEY); // Real SendGrid client
$result = $mailer->send($email); // Real HTTP call to SendGrid!
$this->assertTrue($result->success);
// Fails if: no internet, SendGrid down, API key invalid, rate limited
}
// Guzzle MockHandler — no HTTP in unit tests:
public function testSendConfirmationEmail(): void {
$mock = new MockHandler([new Response(202, [], json_encode(['id'=>'test-123']))]);
$client = new Client(['handler' => HandlerStack::create($mock)]);
$mailer = new SendGridMailer($client); // Injected mock client
$result = $mailer->send($email);
$this->assertTrue($result->success);
$this->assertSame('test-123', $result->messageId);
// Fast, deterministic, no network, no side effects
}