De nombreuses applications de bases de données modernes utilisent le projet Doctrine ORM .
Il est considéré comme une bonne pratique de confier le travail avec la base de données aux services. Et les services doivent être testés.
Pour tester les services, vous pouvez connecter une base de données de test ou verrouiller Entity Manager et les référentiels. Avec la première option, tout est clair, mais cela n'a pas toujours de sens de déployer une base de données pour tester le service. Nous en parlerons.
Par exemple, prenez le service suivant:
src / Service / User / UserService.php Nous devons tester sa seule méthode create()
.
Sélectionnez les cas suivants:
- Création d'utilisateurs réussie sans référent
- Création d'utilisateurs réussie avec référent
- Erreur "Connexion déjà prise"
- Erreur "Référent introuvable"
Pour tester le service, nous avons besoin d'un objet qui implémente l'interface Doctrine\ORM\EntityManagerInterface
Option 1. Nous utilisons une vraie base de données
Nous allons écrire une classe de base pour les tests, dont nous hériterons plus tard.
Maintenant, il est logique que les tests définissent des variables d'environnement. Ajoutez-les au fichier phpunit.xml
dans la section php
. Je vais utiliser sqlite db
phpunit.xml <?xml version="1.0" encoding="UTF-8"?> <phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/8.1/phpunit.xsd" bootstrap="vendor/autoload.php" executionOrder="depends,defects" forceCoversAnnotation="true" beStrictAboutCoversAnnotation="true" beStrictAboutOutputDuringTests="true" beStrictAboutTodoAnnotatedTests="true" verbose="true" colors="true"> <php> <env name="DB_DRIVER" value="pdo_sqlite" /> <env name="DB_PATH" value="var/db-test.sqlite" /> <env name="DB_USER" value="" /> <env name="DB_PASSWORD" value="" /> <env name="DB_NAME" value="" /> </php> <testsuites> <testsuite name="default"> <directory>tests/Unit</directory> </testsuite> </testsuites> <filter> <whitelist processUncoveredFilesFromWhitelist="true"> <directory suffix=".php">src</directory> </whitelist> </filter> </phpunit>
Nous allons maintenant écrire un test de service
tests / Unité / Service / UserServiceTest.php Assurez-vous que notre service fonctionne correctement
./vendor/bin/phpunit
Option 2. Utilisation de MockBuilder
Construire une base de données à chaque fois est difficile. En particulier, phpunit nous donne la possibilité de collecter des moki à la volée en utilisant mockBuilder. Un exemple peut être trouvé dans la documentation Symfony.
Exemple de documentation Symfony L'option fonctionne, mais il y a des problèmes. Vous devez savoir clairement dans quel ordre le code accède aux méthodes EntityManager.
Par exemple, si un développeur échange la vérification de l'existence d'un référent et la vérification d'une connexion occupée, le test échoue. Mais l'application ne l'est pas.
Je propose l'option de moking intelligent EntityManager, qui stocke toutes ses données en mémoire et n'utilise pas une vraie base de données.
Option 3. Nous utilisons MockBuilder avec le stockage de données en mémoire.
Pour plus de flexibilité, nous allons ajouter une variable d'environnement afin que vous puissiez utiliser une vraie base de données. Faisons hivernage dans phpunit.xml
Modifications de phpunit.xml <?xml version="1.0" encoding="UTF-8"?> <php> <env name="EMULATE_BD" value="1" /> </php>
Modifiez maintenant la classe de base
tests modifiés / TestCase.php Nous pouvons maintenant relancer le test et nous assurer que notre service fonctionne sans se connecter à la base de données.
./vendor/bin/phpunit
Code source disponible sur Github