v13.39.0. Para el uso básico, consulta el cliente HTTP, y para preparar el entorno de pruebas, Pruebas de paquetes.
Comparte la Factory y crea un PendingRequest en cada llamada
El cliente HTTP de Laravel incluye objetos con responsabilidades distintas.FoundationServiceProvider registra la Factory como singleton, y la fachada Http también la resuelve desde el contenedor con el mismo nombre de clase. Por eso, en una aplicación Laravel normal, las solicitudes realizadas con la Factory recibida del contenedor también pueden verificarse con Http::fake(). Es posible diseñar el código usando directamente la fachada, pero en esta página se inyecta la Factory para que las dependencias queden explícitas.
Los métodos habituales de configuración de solicitudes, como baseUrl(), que se llaman sobre la Factory se reenvían desde __call() a un nuevo PendingRequest. createPendingRequest() le pasa los callbacks de fake y la restricción de stray requests vigentes en el momento de crearlo, y newPendingRequest() aplica los middleware y las opciones comunes.
Agrupa las operaciones de la API en un cliente pequeño
Como ejemplo, usaremos el paqueteAcme\Catalog, que obtiene productos de una API de catálogo ficticia. src/CatalogClient.php solo guarda la Factory y la URL base, y la solicitud se crea durante la ejecución de product().
product(42, 'ja') y después a product(42) con el mismo cliente, la cabecera Accept-Language añadida en la llamada anterior no se conserva. La configuración común que la aplicación haya definido en la Factory se sigue aplicando a cada solicitud.
- La configuración propia del paquete se aplica al PendingRequest recién creado. Evita configurar
Http::globalOptions()durante la inicialización del paquete, porque afectaría también a comunicaciones que no tienen relación con él. - No envíes nada en el constructor. Diseña el paquete para que resolver el servicio, iniciar Artisan o publicar el archivo de configuración no provoque conexiones a la API externa.
throw()convierte las respuestas 4xx y 5xx enRequestException. Distínguelas deConnectionException, que se produce por fallos de conexión o tiempos de espera agotados, y no sustituyas los fallos por valores de éxito como un array vacío.json(flags: JSON_THROW_ON_ERROR)convierte el JSON no válido enJsonException. El ejemplo solo comprueba si el resultado es un array, así que con una API real valida también los campos obligatorios y los tipos de datos.
Registrar el cliente en el service provider
Prepara la configuración inicial enconfig/catalog.php del paquete. No guardes aquí clientes HTTP ni closures; incluye solo valores que puedan almacenarse en la caché de configuración.
src/CatalogServiceProvider.php fusiona la configuración y pasa la Factory compartida al resolver el cliente. No sobrescribe el binding de la propia Factory.
config/acme-catalog.php por la de la API real. El catalog.example.test del ejemplo es un host ficticio para la explicación y los fakes.
bind(), pero si el objeto que guarda el cliente es un singleton, esa referencia no se vuelve a crear cada vez. Lo importante es no guardar en propiedades el idioma, las credenciales ni los objetos de solicitud propios de cada llamada. Para más detalles, consulta Diseño del ciclo de vida de los servicios de paquetes.
La sobrescritura de la configuración y la actualización de la caché durante el despliegue se tratan en Fusión y caché de la configuración de paquetes. Gestiona la URL base como configuración de confianza de la aplicación y no permitas que la entrada de una solicitud determine libremente el destino de la conexión.
Verificar el cliente real con fakes
Si haces un mock del propio cliente, no podrás comprobar si usa la Factory compartida ni si construye correctamente la URL y las cabeceras. En las pruebas del paquete, resuelve elCatalogClient real desde el contenedor y simula solo las respuestas HTTP.
El siguiente ejemplo se ejecuta en el entorno de pruebas de Orchestra Testbench. En el setUp() de cada prueba se activa preventStrayRequests(). En las pruebas que realizan comunicaciones, configura respuestas solo para las URL esperadas y no añadas un comodín '*'; así también detectarás errores en la URL.
assertSent() verifica que exista al menos una solicitud coincidente. Para no pasar por alto envíos adicionales no previstos, combínalo con assertSentCount(). assertSentInOrder() verifica el número y el orden de las solicitudes, por lo que también sirve para comprobar el aislamiento del estado al usar el mismo cliente varias veces seguidas.
La protección se configura después de parent::setUp(). Esta prueba por sí sola no permite verificar las comunicaciones realizadas mientras arranca el provider, así que mantén un diseño en el que el registro y el arranque no realicen comunicaciones.
Lo que se puede comprobar con fakes es la solicitud que construye el cliente y el procesamiento de las respuestas preparadas. No garantiza la autenticación del servicio real, la conexión TLS, la duración real de los tiempos de espera ni los cambios en la especificación de la API externa. Las verificaciones que implican conexiones externas se realizan por separado en un entorno de verificación preparado de forma explícita.
Verificaciones adicionales para el mantenimiento a largo plazo
Si separas las responsabilidades de la Factory compartida y de cada PendingRequest, la aplicación puede usar directamente los métodos de prueba habituales de Laravel. En lugar de crear primero un mecanismo de fakes propio, prepara una implementación que pase por la Factory compartida y pruebas que lo comprueben.
Fuentes primarias consultadas
- Documentación oficial de Laravel: cliente HTTP
- Documentación oficial de Laravel: desarrollo de paquetes
- Framework v13.39.0: fake, createPendingRequest y __call de Factory
- Framework v13.39.0: configuración de PendingRequest y procesamiento de stubs
- Framework v13.39.0: throw y decodificación JSON de Response
- Framework v13.39.0: destino de resolución y fake de la fachada Http
- Framework v13.39.0: registro singleton en FoundationServiceProvider
- Tests oficiales de Laravel: HttpClientTest