Comment tester en Java un client HTTP sans se connecter ?
C’est cet article datant d’octobre 2000 (!) qui m’a
montré la voie. Il explique en détail le mécanisme utilisé par la JVM pour invoquer le bon composant permettant
d’interpréter correctement un protocole décrit dans une java.net.URL.
Pour montrer l’utilité de ce mécanisme dans un cas de programmation orientée par les tests, je vais prendre l’exemple de
l’écriture d’une classe permettant de géocoder une adresse à travers
l’API Google Maps.
Cette API est accessible à travers le protocole HTTP. Pour ne pas solliciter constamment le service web nous allons donc
mocker l’appel en se basant sur
la documentation du service.
Remplacer le composant HTTP standard
Lors de l’appel à java.net.URL.openStream() la JVM interprète le protocole contenu dans l’URL. Si c’est "http" la
JVM instanciera par défaut une sun.net.www.protocol.http.HttpURLConnection qui gèrera le dialogue avec le serveur. En
définissant la propriété java.protocol.handler.pkgs avec un nom de package, la JVM introspectera ce package suivi du
nom du protocole et de la classe nommée Handler et devant étendre java.net.URLStreamHandler.
Cela se traduit par le code suivant dans notre test unitaire :
Et par les deux classes suivantes dans le package name.lemerdy.sebastian.mock.http :
Cette seconde classe ouvre un fichier dont le chemin dans le classpath est la même que celle de l’URL.
Mise en oeuvre dans l’exemple
Maintenant qu’on a remplacé l’envoi d’une requête HTTP par l’ouverture d’un fichier du classpath on peut donc tester
notre service dont voici un extrait du code :
Enfin voici le test du code ci-dessus :
Puisque le code à tester se connecte à l’URL http://maps.googleapis.com/maps/api/geocode/xml il suffit donc maintenant
de créer un fichier nommé xml dans le package maps.api.geocode et dont le contenu sera envoyé lors de l’éxécution du
test. Ce fichier XML pourra donc ressembler à ceci :