Dans cet article de blog, nous explorerons les défis et les solutions impliqués dans le test d'une API GraphQL à l'aide de Jest et SuperTest. Le voyage a commencé avec la nécessité de simuler des en-têtes, spécifiquement pour l'authentification basée sur des jetons, dans les tests Jest.
Lors du développement du projet Todo Backend GraphQL pour le défi Woovi, j'ai rencontré un obstacle important. J'avais besoin de tester l'authentification de l'API GraphQL, qui repose sur les jetons Web JSON (JWT) transmis dans les en-têtes HTTP. Au départ, j'ai eu du mal à trouver un moyen simple de simuler ces en-têtes dans Jest. La configuration standard de Jest n'était pas suffisante car elle ne gérait pas directement les requêtes et les réponses HTTP de la même manière qu'un vrai serveur.
Après plusieurs essais et erreurs, je suis tombé sur SuperTest, une bibliothèque conçue pour les assertions HTTP. SuperTest étend les fonctionnalités de Jest en vous permettant de tester les serveurs HTTP comme s'il s'agissait de vrais clients. Cette fonctionnalité a permis de simuler des en-têtes, y compris les jetons d'autorisation requis pour l'authentification de mon API.
Avant de plonger dans les tests, configurons l'environnement.
npm install --save-dev jest supertest faker
module.exports = { preset: 'ts-jest', testEnvironment: 'node', };
SuperTest a changé la donne dans ce scénario. Voici comment je l'ai utilisé pour tester les opérations CRUD et l'authentification de l'API.
import { connect, disconnectDatabase } from './mongooseConnection'; import supertest from 'supertest'; import app from './../index'; beforeAll(async () => { await connect(); }); afterAll(async () => { await disconnectDatabase(); });
import { faker } from '@faker-js/faker'; import { graphql } from 'graphql'; import { schema } from '../schema'; async function authUserTest() { const userTest = { name: faker.name.firstName(), email: faker.internet.email(), password: faker.internet.password(), }; const source = ` mutation { register(name: "${userTest.name}", email: "${userTest.email}", password: "${userTest.password}") { token user { name email } } } `; const result = await graphql({ schema, source }); const data = result.data?.register; return data.token; }
Tâches de test des opérations CRUD
it('should create a new task', async () => { const todo = { task: faker.lorem.words(), status: faker.helpers.arrayElement(['pending', 'complete', 'in progress']), }; const query = ` mutation { todo(task: "${todo.task}", status: "${todo.status}") { task status } } `; const { body } = await supertest(app) .post('/graphql') .send({ query }) .set('Accept', 'application/json') .set('Authorization', `Bearer ${await authUserTest()}`); expect(body.data.todo).toMatchObject(todo); });
Récupérer toutes les tâches
it('should retrieve all tasks', async () => { const query = ` query { todos { _id task status } } `; const { body } = await supertest(app) .post('/graphql') .send({ query }) .set('Accept', 'application/json') .set('Authorization', `Bearer ${await authUserTest()}`); expect(body.data.todos).toBeInstanceOf(Array); });
Mettre à jour une tâche
it('should update a task', async () => { const todos = await Todo.find(); const randomTodo = todos[Math.floor(Math.random() * todos.length)]; const updatedTask = faker.lorem.words(); const updatedStatus = faker.helpers.arrayElement(['pending', 'complete', 'in progress']); const query = ` mutation { updateTodo(_id: "${randomTodo._id}", task: "${updatedTask}", status: "${updatedStatus}") { task status } } `; const { body } = await supertest(app) .post('/graphql') .send({ query }) .set('Accept', 'application/json') .set('Authorization', `Bearer ${await authUserTest()}`); expect(body.data.updateTodo.task).toBe(updatedTask); expect(body.data.updateTodo.status).toBe(updatedStatus); });
Supprimer une tâche
it('should delete a task', async () => { const todos = await Todo.find(); const randomTodo = todos[Math.floor(Math.random() * todos.length)]; const query = ` mutation { deleteTodo(_id: "${randomTodo._id}") { _id } } `; const { body } = await supertest(app) .post('/graphql') .send({ query }) .set('Accept', 'application/json') .set('Authorization', `Bearer ${await authUserTest()}`); expect(body.data.deleteTodo._id).toBe(randomTodo._id); });
Exécutez vos tests en utilisant Jest :
npm test
Cette commande exécutera tous les fichiers de test, fournissant un rapport détaillé des résultats.
La difficulté de simuler les en-têtes dans Jest a conduit à la découverte de SuperTest, qui a considérablement simplifié le processus. En tirant parti de SuperTest aux côtés de Jest, j'ai pu tester efficacement l'authentification et les opérations CRUD de l'API GraphQL, garantissant ainsi la sécurité et les fonctionnalités de l'application. Le partage de ce processus d'apprentissage met en évidence le pouvoir de l'apprentissage public et de la résolution de problèmes pilotée par la communauté.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!