Mocker un service Symfony2 dans un test Behat

Cet article a été publié depuis plus de 6 mois, cela signifie que le contenu peut ne plus être d'actualité.

Il arrive fréquemment que l'on soit amené à utiliser des services Web tiers dans les applications que nous concevons. Lors de l'écriture de nos tests, nous utilisons des mocks (bouchons) afin de simuler le comportement de ces derniers.

Dans le cas d'un test Behat le premier réflexe est certainement d'accéder au containeur de dépendances depuis un contexte afin de modifier ce dernier à la volée.

Malheureusement cette solution ne fonctionne pas. Effectivement le conteneur de dépendance n'est pas partagé entre notre application et les contextes utilisées par Behat. Toute modification de nos dépendances est alors sans effet.

Une solution consiste alors à utiliser une configuration du conteneur de dépendances en fonction de l'environnement Symfony utilisé et d'exécuter nos scénarios sur l'environnement correspondant.

Commençons donc par modifier la configuration du service que nous souhaitons mocker (un composant Facebook dans notre exemple) :

# src/AppBundle/Resources/config/services.yml
services:
    app.component.facebook:
        class: %app.component.facebook.class%

Définissons maintenant la classe à utiliser dans le cas "normal" :

# app/config/config.yml
parameters:
    app.component.facebook.class: Component\Facebook\Facebook

Il ne nous reste plus qu'à surcharger ce paramètre lorsque l'on utilise l'application dans son environnement de test :

# app/config/config_test.yml
parameters:
    app.component.facebook.class: AppBundle\Tests\Mock\Component\Facebook\FacebookMock

Maintenant cette configuration terminée, en configurant Behat pour qu'il utilise l'environnement de test de Symfony, les différents scénarios seront exécutés avec la version de l'application utilisant les bouchons.

La technique utilisée ici est simple, mais peut être contraignante si vous avez un certain nombre de classes à "mocker". Sur son blog, Grégoire Pineau (consultant chez SensioLabs) donne une autre alternative pour réaliser cette tâche et surtout plus pertinente si vous travaillez sur de grosses applications.