Ce qui se passe
Tester du code qui appelle une API externe obligeait à choisir entre de vrais appels, lents et dépendants du tiers, et des mocks manuels qui divergent de la vraie réponse. php-vcr a popularisé une troisième voie, enregistrer puis rejouer ; Symfony 8.2 l'intègre au composant HttpClient (contribution d'Imen Ezzine).
Comment ça marche
Le nouveau RecorderHttpClient décore le transport : il couvre le client par défaut comme les clients scopés. Il est
piloté par l'extension SymfonyExtension du PHPUnit Bridge, que la recette Flex déclare dans phpunit.dist.xml ; il
reste à l'activer dans l'environnement test, puis à marquer les tests concernés :
#[UseRecord]
public function testGetRate(): void
{
// le test appelle le service comme d'habitude
}SYMFONY_HTTP_RECORDER=missing vendor/bin/phpunit tests/Service/ExchangeRatesTest.phpCe passage écrit tests/Service/ExchangeRatesTest/testGetRate.har, au format HAR standard, lisible en revue de code
et dans les outils des navigateurs. Commité, le fichier est rejoué partout, CI comprise ; une requête introuvable lève
HarEntryNotFoundException au lieu de sortir sur le réseau. L'appariement se fait sur la méthode, l'URL et le corps,
et les requêtes répétées sont rejouées dans l'ordre, ce qui couvre une boucle d'attente.
Le réseau se décide à l'exécution
L'attribut ne fait que désigner le fichier. C'est SYMFONY_HTTP_RECORDER qui décide, ce qui empêche de committer
par mégarde un test qui interroge la vraie API :
replay, le défaut : rejoue, échoue si la requête manque ;missing: rejoue, et n'enregistre que les requêtes absentes ;record: refait tous les appels et réécrit les fichiers, après un changement d'API ;passthrough: vrais appels sans lire ni écrire, pour vérifier contre le service réel.
Les secrets
Avant toute écriture, les en-têtes Authorization, Cookie et X-Api-Key, et les champs password, api_key,
client_secret ou access_token (requête, formulaire, JSON) sont remplacés par [REDACTED]. La comparaison se fait
aussi sur les valeurs masquées. Les options redact et redact_except ajustent la liste, redactor accepte un
service qui implémente RedactorInterface. Masquer un champ changeant, comme un nonce, l'exclut de l'appariement.
Limite : les réponses rejouées contiennent les valeurs masquées. Un code qui vérifie la signature d'un id_token
demandera un redactor sur mesure.
Source : blog Symfony, en anglais. La configuration
complète du mode test y figure.