web-dev-qa-db-fra.com

Comment puis-je simuler des requêtes HTTP pour PHPUnit?

J'écris un plugin qui fait des demandes à l'API graphique de Facebook. Comme je ne veux pas que mes tests unitaires fassent réellement ces demandes, comment pourrais-je surmonter cela? Ma méthode appelle à la fois wp_remote_get et wp_remote_post. Rechercher semble être un moyen de simuler des fonctions en utilisant runkit, here

Je veux éviter d'avoir des contributeurs nécessitant trop de dépendances, donc j'aimerais éviter la méthode ci-dessus. Y a-t-il d'autres options? Ma classe étend le WP_UnitTestCase donc j'espère que je pourrais utiliser quelque chose des tests unitaires wp?

6
Daithí

Si vous jetez un coup d'œil à WP_HTTP->request() (que toutes les fonctions connexes encapsulent), il fournit un crochet de filtre dans le but de remplacer une demande en faveur du retour de données arbitraires en réponse:

// Allow plugins to short-circuit the request
$pre = apply_filters( 'pre_http_request', false, $r, $url );
if ( false !== $pre )
    return $pre;
12
Rarst

Prenez les résultats que vous obtenez d'une requête valide ou non valide, sérialisez-les en chaînes, puis ajoutez du code qui désérialise la chaîne dans la variable au lieu de faire la demande.

2
Otto

Afin d'isoler davantage votre code, je voudrais envelopper les appels wp_remote_get etc dans une interface avec deux implémentations. Une implémentation appelle wp_remote_get et l'autre renvoie des données de test.

L'utilisation d'un outil tel que runkit dans cette situation élimine votre problème actuel, à savoir que votre code et les API sont trop étroitement couplés, et qu'un niveau d'encapsulation et d'abstraction serait bénéfique.

2
Tom J Nowell

Dans un (deux) mot (s): données fictives. PHPUnit a getMock() disponible pour cela. Comme les autres réponses ont déjà parfaitement convoqué…

  • où obtenir des données fausses valides (Otto) - assurez-vous d’extraire occasionnellement de nouvelles données
  • et où intercepter les données (Rarst)
  • et quels outils utiliser (TomJNowell)

… Il ne reste que le problème de l'échec de la vérification de votre certificat SSL local. WP est livré avec un filtre pour cela:

add_filter( 'https_local_ssl_verify', '__return_false' );

Pour plus d'informations sur l'API HTTP WP, vous souhaiterez peut-être accéder à cette réponse , cette réponse , cette réponse de @Wyck et cette réponse de @toscho .

1
kaiser

J'ai dû me moquer des fonctions de requête HTTP de WordPress à quelques reprises et j'ai donc décidé de créer un outil permettant de le faire: WP HTTP TestCase

Fondamentalement, cela fournit un moyen facile de faire les différentes choses que les autres réponses ont esquissées. Du readme:

WP Testcase HTTP

PHPUnit testcase pour tester du code utilisant la classe WP_Http de WordPress.

Si vous utilisez wp_remote_request() ou d'autres wrappers pour les méthodes WP_Http dans votre code, le test est difficile, en particulier si le serveur distant n'est peut-être pas accessible à partir de votre environnement de test. Ce cas de test résout ce problème en vous permettant de router vos demandes vers une autre adresse d'hôte, d'utiliser un ensemble de réponses en cache ou de simuler les réponses distantes en fournissant des réponses artificielles.

Installation

Vous pouvez installer ce paquet en utilisant composer:

composer require --dev jdgrimes/wp-http-testcase:~1.1

Usage

Pour l'utiliser dans votre code, vous devez d'abord inclure le fichier wp-http-testcase.php dans votre fichier d'amorçage PHPUnit. Si vous souhaitez utiliser les fonctionnalités de routage de l'hôte et de mise en cache des réponses, vous devrez appeler WP_HTTP_TestCase::init() dans votre fichier d'amorçage.

Ensuite, dans vos tests impliquant WP_Http, vous devez étendre WP_HTTP_TestCase au lieu de WP_UnitTestCase comme vous le feriez normalement.

Réponses moqueuses

Utilisation de la mise en cache de réponse

La meilleure façon de tester, lorsque cela est possible, est de configurer un hôte fictif pour gérer les demandes. Dans certains cas, vous pouvez ou devez réellement envoyer les demandes via le serveur réel, et cela peut également être fait. Ce que vous ferez dépendra de la nature des demandes et des effets secondaires qu'elles produisent sur l'hôte destinataire.

Configuration d'un hôte de test

Par exemple, si vous testez un plug-in qui envoie des requêtes à une API fournie par un autre plug-in ou un autre logiciel, vous ne souhaitez probablement pas ou n'avez pas besoin de le tester sur un site actif. Au lieu de cela, vous pouvez configurer un site de test ou utiliser un serveur local faisant partie de votre environnement de développement. Là, vous pouvez installer le logiciel qui gère les demandes. Une fois que cela est fait, vous pouvez exécuter vos tests sur ce site de test de la manière suivante:

WP_HTTP_TC_Host=localhost phpunit

Il suffit de remplacer localhost par le nom d'hôte du serveur local. Notez que les indicateurs WP_HTTP_TC_* peuvent être définis en tant que constantes PHP ou en tant que variables d'environnement bash comme ci-dessus. Ce dernier aura la priorité.

Activation de la mise en cache

Bien sûr, cela sera beaucoup plus lent que la plupart des autres tests unitaires, car les requêtes prendront un peu de temps. C'est là qu'intervient la mise en cache. Lorsque la mise en cache est activée, la réponse à chaque demande est mise en cache lors de la première exécution, et la version mise en cache est utilisée dans le futur. Cela signifie que vos tests peuvent rester extrêmement rapides.

Pour activer la mise en cache, ajoutez simplement ceci à votre bootstrap:

define( 'WP_HTTP_TC_USE_CACHING', true );

Vous voudrez probablement aussi spécifier le répertoire dans lequel enregistrer le cache, via WP_HTTP_TC_CACHE_DIR. Vous pouvez utiliser plusieurs groupes de cache et basculer entre eux à l'aide de WP_HTTP_TC_CACHE_GROUP.

Utiliser l’animateur

Il existe cependant le deuxième cas où vous ne pouvez pas configurer de serveur de test. Ce serait le cas, par exemple, si votre plug-in adresse des requêtes à l'API fournie par GitHub. Selon la situation, il peut être possible de transmettre les demandes au destinataire "en direct". Le problème principal encore est que les demandes rendront les tests longs. Il est également possible que l'API ne soit pas toujours accessible depuis votre environnement de test ou que vos tests finissent par le marteler trop et que vous soyez bloqué. C’est là que la mise en cache peut vous aider. Il vous suffit d'exécuter vos tests avec l'API "live" de temps en temps, et le reste du temps, vous pouvez tester à l'aide des réponses mises en cache.

Fournir des réponses artificielles

Bien sûr, il peut arriver qu’il ne soit pas possible de créer un serveur de test et qu’il soit également impossible de s’exécuter sur le serveur actif. Dans ce cas, vous pouvez coder en dur des réponses artificielles dans vos tests. Voici comment vous pouvez faire cela:

Avant d'appeler le code qui appellera la requête HTTP, vous devez configurer la fonction pour simuler les réponses de la manière suivante:

$this->http_responder = array( $this, 'mock_server_response' );

La fonction de répondeur HTTP recevra deux arguments, les arguments de requête et l'URL à laquelle la requête était destinée.

protected function mock_server_response( $request, $url ) {
   return array( 'body' => 'Test response.' ); 
}

Pour une liste complète des arguments $request et de réponse, voir WP_Http::request()

1
J.D.