Interview frequency: …
Short answer
Http::fake intercepts HTTP client calls and returns predefined responses by pattern; Http::preventStrayRequests() blocks any unmocked request from reaching the real network.
Explanation
Define a response for each URL (or a * pattern) with Http::response, and fake failures (500 and timeouts) to test retry and fallback logic. Http::sequence() returns different responses for each call to simulate a temporary failure followed by success. After execution, verify requests with Http::assertSent (URL, body, and headers) and assertSentCount. Enable preventStrayRequests in setUp so tests cannot accidentally access the internet and become slow or flaky.
Code example
protected function setUp(): void
{
parent::setUp();
Http::preventStrayRequests(); // any request without a matching fake throws an exception
}
public function test_it_charges_the_card(): void
{
Http::fake([
'api.payments.test/charge' => Http::response(['status' => 'paid'], 200),
'api.payments.test/*' => Http::response([], 500),
]);
$result = app(PaymentGateway::class)->charge(amount: 100);
$this->assertTrue($result->paid);
Http::assertSent(fn (Request $r) => $r->url() === 'https://api.payments.test/charge' && $r['amount'] === 100);
Http::assertSentCount(1);
}
public function test_it_retries_after_a_temporary_failure(): void
{
Http::fake([
'api.payments.test/*' => Http::sequence()
->push([], 503)
->push(['status' => 'paid'], 200),
]);
$this->assertTrue(app(PaymentGateway::class)->charge(amount: 100)->paid);
Http::assertSentCount(2);
}Common mistakes
- Leaving tests that call real APIs, causing failures when the internet is unavailable or the external service changes.
- Faking only successful requests without testing the failure and timeout paths used by recovery logic.