v13.39.0. Pour les opérations de base, consultez Client HTTP, et pour préparer l’environnement de test, consultez Tester des packages.
Partager la Factory, créer une PendingRequest à chaque fois
Le client HTTP de Laravel repose sur des objets aux responsabilités distinctes.FoundationServiceProvider enregistre la Factory en singleton, et la façade Http est résolue depuis le conteneur avec le même nom de classe. Ainsi, dans une application Laravel classique, les échanges effectués via la Factory reçue du conteneur peuvent aussi être vérifiés avec Http::fake(). Il est possible d’utiliser directement la façade, mais cette page injecte la Factory afin de rendre les dépendances explicites.
Les méthodes habituelles de configuration de requête appelées sur la Factory, comme baseUrl(), sont transférées par __call() vers une nouvelle PendingRequest. createPendingRequest() transmet les callbacks de fake et la restriction des stray requests en vigueur au moment de la création, et newPendingRequest() applique les middlewares et options communs.
Regrouper les opérations d’API dans un petit client
Prenons l’exemple d’un packageAcme\Catalog qui récupère des produits depuis une API de catalogue fictive. src/CatalogClient.php ne conserve que la Factory et l’URL de base, et la requête est créée pendant l’exécution de product().
product(42) après product(42, 'ja') sur le même client, l’en-tête Accept-Language ajouté lors de l’appel précédent ne subsiste pas. La configuration commune définie sur la Factory par l’application consommatrice continue de s’appliquer à chaque requête.
- Appliquez la configuration propre au package sur la PendingRequest nouvellement créée. Évitez de définir
Http::globalOptions()lors de l’initialisation du package, car cela affecterait aussi des échanges sans rapport. - N’envoyez rien dans le constructeur. Concevez le package pour que la simple résolution du service, le démarrage d’Artisan ou la publication du fichier de configuration ne se connectent pas à l’API externe.
throw()convertit les 4xx et 5xx enRequestException. Distinguez-les desConnectionExceptiondues à un échec de connexion ou à un timeout, et ne remplacez pas un échec par une valeur de succès comme un tableau vide.json(flags: JSON_THROW_ON_ERROR)convertit un JSON invalide enJsonException. L’exemple vérifie seulement qu’il s’agit d’un tableau ; avec une vraie API, validez aussi les champs obligatoires et les types de données.
Enregistrer le client dans un service provider
Préparez la configuration initiale dansconfig/catalog.php du package. N’y stockez ni client HTTP ni closure ; ne mettez que des valeurs pouvant être placées dans le cache de configuration.
src/CatalogServiceProvider.php fusionne la configuration et transmet la Factory partagée lors de la résolution du client. Il ne remplace pas le binding de la Factory elle-même.
config/acme-catalog.php par celle de la vraie API. Le catalog.example.test de l’exemple est un hôte fictif destiné aux explications et aux fakes.
bind(), mais si l’objet qui conserve le client est un singleton, cette référence n’est pas recréée à chaque fois. L’essentiel est de ne pas stocker dans des propriétés la langue, les identifiants d’authentification ou l’objet de requête propres à un appel. Pour plus de détails, consultez Concevoir le cycle de vie des services d’un package.
La surcharge de la configuration et la mise à jour du cache lors du déploiement sont traitées dans Fusion et cache de la configuration d’un package. Gérez l’URL de base comme une configuration d’application de confiance, et ne laissez pas les entrées de requête désigner librement la destination.
Vérifier le vrai client avec des fakes
Si vous mockez le client lui-même, vous ne pouvez pas vérifier qu’il utilise la Factory partagée ni qu’il construit correctement l’URL et les en-têtes. Dans les tests du package, résolvez le vraiCatalogClient depuis le conteneur et ne simulez que les réponses HTTP.
Voici un exemple exécuté dans l’environnement de test Orchestra Testbench. preventStrayRequests() est activé dans le setUp() de chaque test. Dans les tests qui communiquent, définissez des réponses uniquement pour les URL attendues et n’ajoutez pas de repli '*', afin de détecter aussi les erreurs d’URL.
assertSent() vérifie qu’au moins une requête correspondante existe. Combinez-le avec assertSentCount() pour ne pas laisser passer des envois supplémentaires non souhaités. assertSentInOrder() vérifie le nombre et l’ordre des requêtes, ce qui permet aussi de contrôler l’isolation de l’état lorsque le même client est utilisé plusieurs fois de suite.
La protection est configurée après parent::setUp(). Ce test seul ne permet pas de vérifier les échanges effectués pendant le démarrage du provider ; conservez donc une conception qui ne communique pas lors de l’enregistrement et du démarrage.
Les fakes permettent de vérifier les requêtes construites par le client et le traitement des réponses préparées. Ils ne garantissent ni l’authentification du vrai service, ni la connexion TLS, ni les durées réelles de timeout, ni les changements de spécification de l’API externe. Les vérifications impliquant des connexions externes doivent être menées séparément, dans un environnement de test explicitement préparé.
Vérifications à ajouter pour la maintenance à long terme
En séparant les responsabilités de la Factory partagée et de chaque PendingRequest, l’application consommatrice peut utiliser telles quelles les méthodes de test habituelles de Laravel. Plutôt que de commencer par créer votre propre mécanisme de fake, préparez d’abord une implémentation qui passe par la Factory partagée et les tests qui le vérifient.
Sources primaires consultées
- Documentation officielle de Laravel : HTTP Client
- Documentation officielle de Laravel : Package Development
- Framework v13.39.0 : fake, createPendingRequest et __call de Factory
- Framework v13.39.0 : configuration et traitement des stubs de PendingRequest
- Framework v13.39.0 : throw et décodage JSON de Response
- Framework v13.39.0 : cible de résolution et fake de la façade Http
- Framework v13.39.0 : enregistrement en singleton dans FoundationServiceProvider
- Tests officiels de Laravel : HttpClientTest