Partie 4 - Tests unitaires

Publié le 16/01/2025 Source : sfeir.dev

Jour 4 : La mer commence à s’agiter à l’approche du Cap des bons Tests

musique de fond pour l’article


Arrr ! Notre API a été dressée comme un fier matelot, mais avant de la laisser naviguer dans l’infini des requêtes, nous devons l’éprouver à la manière des vieux loups de mer : avec des tests unitaires.
Car comme le dirait le capitaine Crochet :

Après tout, à quoi ressemblerait le monde sans les tests unitaires ?

Pas certain de la fin de la citation

En cette journée, notre mission est claire : vérifier que chaque requête et chaque mutation fonctionnent sans faillir. Nous testerons la logique dans nos services et nous nous assurerons que nos contrôleurs manœuvrent les données et gèrent les erreurs avec précision. Nous savons bien ce qu’il advient de ceux qui osent naviguer sans tester leurs canons… et ce n’est guère glorieux.

Armer le POM pour les tests

Avant de tracer notre carte au trésor des tests, il nous faut renforcer notre navire. Pour ce faire, nous ajoutons une dépendance vitale à notre pom.xml :

<dependency>
    <groupId>org.springframework.graphql</groupId>
    <artifactId>spring-graphql-test</artifactId>
    <scope>test</scope>
</dependency>

Ce précieux ajout nous fournit plusieurs outils pour nous permettre de tester nos API GraphQL comme il se doit.

GraphQlTester, notre boussole

La dépendance nous apporte notamment GraphQlTester, un allié robuste, taillé pour envoyer requêtes et mutations en mer sans se perdre dans les configurations. GraphQlTester est notre compas : il nous permet de simuler les interactions avec notre API, un peu comme MockMvc pour REST. Grâce à lui, nous pouvons :

  1. Simuler des requêtes et tester la réponse JSON,
  2. Charger uniquement les composants nécessaires pour les tests, allégeant ainsi notre navire,
  3. Valider les réponses pour s’assurer que tout fonctionne dans les règles de l’art,
  4. Gérer les erreurs éventuelles en évitant que notre navire ne sombre dans les profondeurs des bugs.

Ecrivons la carte au trésor de notre Test

Voici une classe de test qui nous guide sur cette route tortueuse :

@GraphQlTest(AuthorController.class)
public class AuthorControllerTest {
    @Autowired
    private GraphQlTester graphQlTester;

    @MockBean
    private AuthorService authorService;

    @Test
    void givenNewAuthorData_whenExecuteMutation_thenNewAuthorCreated() {

        when(authorService.createAuthor(anyString(), anyString())).thenReturn(mockAuthor());

        String documentName = "create_author";

        graphQlTester.documentName(documentName)
                .variable("name", "Erwan")
                .variable("bio", "J'aime le code")
                .execute()
                .path("createAuthor.id").hasValue()
                .path("createAuthor.name").entity(String.class).isEqualTo("Erwan")
                .path("createAuthor.bio").entity(String.class).isEqualTo("J'aime le code");
    }

    private Author mockAuthor() {
        Author author = new Author();
        author.setId(1L);
        author.setName("Erwan");
        author.setBio("J'aime le code");
        return author;
    }
}

Que pouvons nous voir dans cette classe ?

Décodage des symboles sur la carte

Dans notre classe de test, plusieurs annotations nous servent de balises dans cette aventure :

GraphQlTester en action

GraphQlTester est l’équivalent de MockMvc pour les API REST, il permet aux développeurs d’interagir directement avec les endpoints GraphQL et de valider facilement les réponses JSON, sans avoir à démarrer un serveur Web complet.

Préparer et envoyer la requête GraphQL

Exécuter la mutation

Vérifier la réponse du contrôleur

Utilisation de document

Dans notre test, nous pouvons voir que GraphQlTester utilise un document pour exécuter la requête :

String documentName = "create_author";
graphQlTester.documentName(documentName)

Mais à quoi sert donc ce document, et où se trouve t’il ?

Pour la question sur la localisation du document, la réponse est simple : dans un répertoire graphql-test présent dans les resources de nos tests.

Les documents .graphql, tels que create_author, servent de cartes détaillées pour nos expéditions. Plutôt que de graver chaque requête dans notre test, nous faisons appel à un document séparé. Cela a plusieurs avantages :

Conclusion

L’approche avec @GraphQlTest et les documents .graphql rend les tests plus clairs et organisés, tout en favorisant la réutilisabilité des requêtes et mutations. En utilisant GraphQlTester, on bénéficie d’un contrôle précis sur les réponses JSON, ce qui permet de tester efficacement toutes les parties de l’API GraphQL sans dépendre d’une base de données.

Avec cette structure, nos tests sont modulaires et peuvent facilement évoluer avec les besoins de l’application. Cela garantit une couverture fiable et maintenable pour l’ensemble des API GraphQL de notre projet.


Après avoir franchi le Cap des bons Tests sans embûches, nous mettons le cap sur l’île de la Documentation, prêts à partager nos exploits avec le monde.

Précédemment

Partie 3 - Controllers

Prochainement

Partie 5 - Documentation