Navigation

Laravel

How to Fake HTTP Responses for Easy Testing (`Http::fake`)

Mock external API responses in Laravel tests using Http::fake to avoid real HTTP calls. Perfect for testing integrations without dependencies.

Testing external APIs is like trying to test your car while stuck in traffic - unpredictable and frustrating. Laravel's Http::fake() is your test track where everything works perfectly:

Use Http::fake() to mock HTTP responses in your tests:

use Illuminate\Support\Facades\Http;

// In your test
public function test_user_can_fetch_external_data()
{
    // Fake all HTTP requests
    Http::fake([
        'api.example.com/*' => Http::response([
            'users' => [
                ['id' => 1, 'name' => 'John'],
                ['id' => 2, 'name' => 'Jane']
            ]
        ], 200),
        
        'payments.stripe.com/*' => Http::response([
            'status' => 'success',
            'payment_id' => 'pay_123'
        ], 200)
    ]);
    
    // Your code that makes HTTP requests
    $response = $this->post('/api/sync-users');
    
    $response->assertStatus(200);
    
    // Assert HTTP requests were made
    Http::assertSent(function ($request) {
        return $request->url() === 'https://api.example.com/users';
    });
}

Different faking strategies:

// Fake all requests with same response
Http::fake();

// Fake specific URLs
Http::fake([
    'github.com/*' => Http::response(['name' => 'Laravel'], 200),
    'api.stripe.com/*' => Http::response(['error' => 'Invalid key'], 401),
]);

// Fake with callbacks
Http::fake(function ($request) {
    if ($request->url() === 'https://api.example.com/users') {
        return Http::response(['users' => []], 200);
    }
    
    return Http::response([], 404);
});

// Fake sequences for multiple calls
Http::fake([
    'api.example.com/*' => Http::sequence()
        ->push(['status' => 'pending'], 200)
        ->push(['status' => 'completed'], 200)
        ->pushStatus(404)
]);

Table Of Contents

Behind the Scenes

When you call Http::fake(), Laravel intercepts any outgoing HTTP requests and serves your predefined responses instead. It's like having a mock server that always gives you exactly what you expect - no network delays, no API limits, no service outages.

Complete testing example:

public function test_api_service_handles_failures_gracefully()
{
    // Mock API failure
    Http::fake([
        'api.external.com/*' => Http::response([], 500)
    ]);
    
    // Test your service
    $service = new ExternalApiService();
    
    $this->expectException(ApiException::class);
    $service->fetchUserData();
    
    // Verify the request was attempted
    Http::assertSent(function ($request) {
        return str_contains($request->url(), 'api.external.com/users');
    });
    
    // Verify headers were sent correctly
    Http::assertSent(function ($request) {
        return $request->hasHeader('Authorization', 'Bearer test-token');
    });
}

// Test multiple requests
public function test_service_makes_correct_api_calls()
{
    Http::fake();
    
    $service = new UserSyncService();
    $service->syncUsers();
    
    // Assert specific requests were made
    Http::assertSentCount(2);
    Http::assertSent(fn($request) => $request->url() === 'https://api.users.com/list');
    Http::assertSent(fn($request) => $request->url() === 'https://api.profiles.com/batch');
    Http::assertNotSent(fn($request) => str_contains($request->url(), 'analytics.com'));
}

Related: Laravel Collections: Beyond Basic Array Operations | Unit Testing Tutorial for Beginners | Laravel Testing: Unit, Feature and Integration Tests | Laravel Testing: Unit, Feature and Integration Tests | Laravel Dusk: Browser Testing Advanced Techniques

Share this article

Add Comment

No comments yet. Be the first to comment!

More from Laravel