Saltar al contenido

Imagina este escenario: tienes un test que verifica la integración con una API externa. Has configurado tu Http::fake() y el test pasa. Todo parece correcto.

Pero hay un problema: te has equivocado en la URL del fake, o alguien ha cambiado el endpoint en el código. El test sigue pasando, pero está haciendo peticiones reales a la API sin que te des cuenta.

El problema de las peticiones HTTP no controladas

Cuando un test hace peticiones HTTP reales sin que lo sepas, pueden pasar varias cosas:

  • Tests lentos: una petición real tarda mucho más que un mock.

  • Falsos positivos: el test pasa porque la API externa responde correctamente, no porque tu código esté bien.

  • Tests inestables: si la API externa falla o tiene latencia, tu CI se vuelve impredecible.

  • Costes inesperados: si la API es de pago, puedes llevarte sorpresas en la factura.

  • Datos reales modificados: en el peor caso, podrías estar creando o modificando datos reales.

La solución: Http::preventStrayRequests()

Laravel incluye un método que resuelve exactamente este problema. Al activarlo, cualquier petición HTTP que no esté explícitamente fakeada lanzará una excepción:

<?php

use Illuminate\Support\Facades\Http;

Http::preventStrayRequests();

Http::fake([
    'api.example.com/users' => Http::response(['id' => 1, 'name' => 'John']),
]);

// Esta petición funciona porque está fakeada
$response = Http::get('api.example.com/users');

// Esta petición lanza una excepción porque NO está fakeada
$response = Http::get('api.example.com/products');

Si ejecutas este código, Laravel lanzará una excepción clara indicando que se ha intentado hacer una petición a una URL no mockeada.

Configuración recomendada con Pest

La mejor práctica es activar preventStrayRequests() de forma global para toda tu suite de tests. En Pest, puedes hacerlo en el beforeEach() de tu archivo Pest.php:

<?php

use Illuminate\Support\Facades\Http;

beforeEach(function () {
    Http::preventStrayRequests();
});

De esta forma, cada test arranca con la protección activada. Si alguien añade un test nuevo y se le olvida fakear una petición, Pest le avisará inmediatamente.

Configuración con PHPUnit

Si usas PHPUnit directamente, puedes añadirlo en el método setUp() de tu TestCase base:

<?php

namespace Tests;

use Illuminate\Foundation\Testing\TestCase as BaseTestCase;
use Illuminate\Support\Facades\Http;

abstract class TestCase extends BaseTestCase
{
    protected function setUp(): void
    {
        parent::setUp();
        
        Http::preventStrayRequests();
    }
}

Ejemplo práctico

Supongamos que tienes un servicio que consulta una API de pagos:

<?php

namespace App\Services;

use Illuminate\Support\Facades\Http;

class PaymentService
{
    public function getTransaction(string $id): array
    {
        $response = Http::get("https://api.payments.com/transactions/{$id}");
        
        return $response->json();
    }
}

Tu test con Pest podría verse así:

<?php

use App\Services\PaymentService;
use Illuminate\Support\Facades\Http;

it('retrieves a transaction from the payment API', function () {
    Http::fake([
        'api.payments.com/transactions/123' => Http::response([
            'id' => '123',
            'amount' => 100,
            'status' => 'completed',
        ]),
    ]);

    $service = new PaymentService();
    $transaction = $service->getTransaction('123');

    expect($transaction)
        ->id->toBe('123')
        ->amount->toBe(100)
        ->status->toBe('completed');
});

Si mañana alguien cambia la URL base de la API a https://api.payments.io y se olvida de actualizar el test, preventStrayRequests() detectará que la petición no coincide con ningún fake y lanzará una excepción.

Conclusión

Http::preventStrayRequests() es una de esas funcionalidades pequeñas que marcan la diferencia en la calidad de tus tests. Te obliga a ser explícito con tus mocks y te avisa inmediatamente cuando algo no está configurado correctamente.

Actívalo de forma global en tu suite de tests y olvídate de las peticiones HTTP fantasma que pasan desapercibidas.

school Curso completo

Curso Laravel 12
Completo 2026

El único curso 100% actualizado que incluye Laravel 12, Livewire 3, Vue 3, React 19 e Inertia 2. Aprende con proyectos reales y las últimas funcionalidades.

access_time 8 horas de contenido
layers 4 tecnologías en 1
update 100% actualizado
code Proyectos prácticos
Ver Curso Laravel 12 arrow_forward

star Incluido en cualquier suscripción

Rutas de aprendizaje