Seluruh section ini kita bersandar pada satu teknik diam-diam: Http::fake(). Kini saatnya membahasnya secara penuh sebagai alat testing. Kode yang memanggil API eksternal adalah kode yang paling rewel diuji — hasilnya bergantung server orang lain, jaringan, dan kuota. Tanpa mocking, test suite berjalan lambat, gagal sewaktu-waktu (flaky), dan tidak bisa mensimulasikan keadaan darurat seperti server down. Laravel menutup semua masalah itu dengan satu fasad: Http::fake() mencegat request sebelum menyentuh jaringan, lalu Http::assertSent() memverifikasi bentuk request yang terkirim. Kita rangkum semua polanya dalam satu test suite sungguhan.
fake Selimut dan fake per URL #
Bentuk paling sederhana menutup semua URL sekaligus — berguna saat isi response tidak penting, yang diuji adalah perilaku kode kita:
<?php
// tests/Feature/HttpClientMockingTest.php (potongan)
public function test_fake_selimut_menutup_semua_url(): void
{
Http::fake();
$response = Http::post('https://api.example.com/tasks', ['judul' => 'Belajar']);
$this->assertSame(200, $response->status());
$this->assertSame('', $response->body());
}Panggilan Http::fake() tanpa argumen mengembalikan response 200 dengan body kosong untuk URL mana pun. Untuk kontrol penuh, berikan array yang memetakan pola URL ke response — hanya URL yang cocok yang dijawab:
<?php
public function test_fake_per_url_dengan_data(): void
{
Http::fake([
'api.example.com/tasks' => Http::response([
['id' => 1, 'judul' => 'Belajar HTTP Client'],
], 200),
'api.example.com/profil' => Http::response(['pesan' => 'tidak ada'], 404),
]);
$tasks = Http::get('https://api.example.com/tasks');
$profil = Http::get('https://api.example.com/profil');
$this->assertSame(200, $tasks->status());
$this->assertSame('Belajar HTTP Client', $tasks->json('0.judul'));
$this->assertSame(404, $profil->status());
}Pola api.example.com/tasks mencocokkan URL mana pun yang mengandung string tersebut; tanda * tersedia untuk wildcard seperti api.example.com/*.
fakeSequence untuk Request Berurutan #
Endpoint yang dipanggil berkali-kali butuh jawaban berbeda-beda — misalnya skenario token dari chapter Authentication dan Headers
: Http::sequence() menyajikan response satu per satu sesuai urutan pemanggilan:
<?php
public function test_fake_sequence_untuk_urutan_request(): void
{
Http::fake([
'api.example.com/token' => Http::sequence()
->push(['token' => 'TOKEN_SATU'], 200)
->push(['token' => 'TOKEN_DUA'], 200),
]);
$satu = Http::get('https://api.example.com/token')->json('token');
$dua = Http::get('https://api.example.com/token')->json('token');
$this->assertSame('TOKEN_SATU', $satu);
$this->assertSame('TOKEN_DUA', $dua);
}Panggilan ketiga pada sequence yang habis akan memunculkan exception — tambahkan ->whenEmpty(Http::response()) bila kita ingin sisa pemanggilan mendapat response default.
assertSent: Memeriksa yang Terkirim #
Menguji response hanya separuh cerita; test yang kuat juga memverifikasi request — method, URL, dan body. Method assertSent() menerima closure yang menerima object Request:
<?php
public function test_assert_sent_memeriksa_method_url_dan_body(): void
{
Http::fake();
Http::post('https://api.example.com/tasks', [
'judul' => 'Belajar HTTP Client',
'prioritas' => 'tinggi',
]);
Http::assertSent(function ($request) {
return $request->method() === 'POST'
&& $request->url() === 'https://api.example.com/tasks'
&& $request['prioritas'] === 'tinggi';
});
Http::assertNotSent(fn ($request) => $request->url() === 'https://api.example.com/lain');
}Object $request membuka seluruh isi panggilan: method(), url(), header($nama), body() untuk raw string, dan akses array $request['kunci'] untuk data JSON maupun form. Lawannya, assertNotSent() memastikan request tertentu tidak pernah terkirim.
Menutup Celah Request Liar #
Fake per URL punya celah: kesalahan ketik di base URL membuat request lolos ke jaringan sungguhan dan test tetap hijau padahal tidak menguji apa pun — atau lebih buruk, gagal mendadak saat jaringan sungguhan dijawab berbeda. Http::preventStrayRequests() menutupnya: request ke URL tanpa fake yang cocok langsung melempar StrayRequestException dengan pesan Attempted request to [...] without a matching fake:
<?php
public function test_prevent_stray_requests_menolak_url_asing(): void
{
Http::preventStrayRequests();
Http::fake([
'api.example.com/tasks' => Http::response(['pesan' => 'oke'], 200),
]);
$response = Http::get('https://api.example.com/tasks');
$this->assertSame(200, $response->status());
$this->expectException(\Illuminate\Http\Client\StrayRequestException::class);
Http::get('https://layanan-lain.com/data');
}Stub juga bisa mensimulasikan kegagalan jaringan total — bukan sekadar response error, melainkan koneksi yang tidak pernah terjadi. Fake yang melempar ConnectionException membuktikan penanganan catch kita benar-benar berjalan:
<?php
public function test_stub_exception_jaringan(): void
{
Http::fake(fn () => throw new ConnectionException('Koneksi gagal'));
$this->expectException(ConnectionException::class);
Http::retry(2, 0)->get('https://api.example.com/tasks');
}Test Suite Lengkap Berjalan #
Ketujuh test di atas adalah satu file nyata yang kita jalankan di sandbox:
php artisan test tests/Feature/HttpClientMockingTest.phpOutput yang Dihasilkan:
PASS Tests\Feature\HttpClientMockingTest
✓ fake selimut menutup semua url 0.10s
✓ fake per url dengan data 0.01s
✓ fake sequence untuk urutan request 0.01s
✓ assert sent memeriksa method url dan body 0.01s
✓ assert sent count dengan retry 0.01s
✓ prevent stray requests menolak url asing 0.01s
✓ stub exception jaringan 0.01s
Tests: 7 passed (14 assertions)
Duration: 0.21sTujuh test, empat belas assertion, nol koneksi internet — seluruh suite selesai dalam seperlima detik. Itulah janji yang ditepati Http::fake() sejak chapter pertama section ini: deterministik, cepat, dan tetap menguji jalur kode yang sama persis dengan produksi. Ingat juga bahwa fake bekerja pada instance HttpFactory di container, sehingga service class dari chapter Mengintegrasikan Layanan Eksternal
otomatis teruji tanpa perubahan satu baris pun. Daftar lengkap semua assertion tersedia di bagian testing dokumentasi HTTP Client
— dan dengan itu, perjalanan kita menguasai HTTP Client Laravel resmi lengkap.