Le test, même s'il peut prendre du temps, est une étape importante dans le cycle de développement de toute application. Cela vous permet de détecter les bogues et les problèmes tôt avant de pousser le code en production.
Vous pouvez utiliser Jest pour tester une API Express Rest. Après avoir créé une API CRUD simple, découvrez comment écrire des tests pour chaque point de terminaison.
Qu'est-ce que la plaisanterie ?
Il existe de nombreuses bibliothèques de test JavaScript parmi lesquelles vous pouvez choisir, mais Plaisanter est le plus simple pour commencer. Il s'agit d'une bibliothèque de test développée par Facebook, principalement utilisée pour tester les projets React. Cependant, vous pouvez également l'utiliser pour tester Node et d'autres projets basés sur JavaScript. Il a été développé sur Jasmine, un autre outil de test, et est fourni avec sa propre bibliothèque d'assertions.
Bien que vous n'ayez pas besoin d'une bibliothèque d'assertions pour écrire des tests dans Jest, vous devrez utiliser un outil pour effectuer des requêtes HTTP. Cet article utilise SuperTest.
Qu'est-ce que SuperTest ?
SuperTest est une bibliothèque de test Node pour les appels HTTP. Il étend la bibliothèque de test de superagent et vous permet de faire des requêtes telles que GET, POST, PUT et DELETE.
SuperTest fournit un objet de requête que vous pouvez utiliser pour effectuer des requêtes HTTP.
constante demande = exiger("supertest")
demande("https://icanhazdadjoke.com")
.obtenir('/slack')
.fin(fonction(erreur, res) {
si (se tromper) jeter se tromper;
console.Journal(res.corps.pièces jointes);
});
Ici, vous transmettez l'URL de base de l'API à l'objet de requête, puis vous enchaînez la méthode HTTP avec le reste de l'URL. La fin() La méthode appelle le serveur API et la fonction de rappel gère sa réponse.
Une fois que vous obtenez la réponse de l'API, vous pouvez utiliser Jest pour la valider.
Créer une API Express
Pour tester vos propres points de terminaison d'API, vous devez créer une API REST première. L'API que vous allez créer est assez simple. Il insère, récupère, met à jour et supprime des éléments d'un tableau.
Commencez par créer un nouveau répertoire appelé node-jest et initialisez npm.
nœud mkdir-jest
npm init -y
Ensuite, créez un nouveau fichier appelé index.js et créer le serveur Express.
constante exprimer = exiger("Express")
constante app = express()
app.listen (3000, () => console.log("Écoute au port 3000"))
Testez le point de terminaison GET /todos
Le premier point de terminaison que vous allez créer est le point de terminaison GET /todos. Il renvoie tous les éléments du tableau. Dans index.js, ajoutez ce qui suit.
constante todos = [
];
// Récupère toutes les tâches
app.get("/todos", (req, res) => {
revenirres.statut(200).json({
données: tâches à effectuer,
Erreur: nul,
});
});
Notez que la réponse a un code d'état de 200 et un objet JSON contenant l'élément de tâches dans un tableau appelé données et un message d'erreur. C'est ce que vous allez tester avec Jest.
Maintenant, installez Jest et SuperTest :
npm installer Supertest de plaisanterie
Ensuite, ajoutez un script de test dans package.json comme suit:
{
"scénarios": {
"test": "plaisanter"
}
}
Avant de commencer à écrire vos propres tests, vous devez comprendre comment écrire un test de base dans Jest.
Considérez la fonction suivante :
fonctionsomme(un B) {
revenir un + b ;
}
module.exportations = somme ;
Dans le fichier de test, vous devez :
- Importez la fonction.
- Décrivez ce que le test doit faire.
- Appelez la fonction.
- Confirmez la réponse attendue avec la réponse réelle de la fonction.
constante { somme } = exiger("./somme")
décris("Somme de deux éléments", asynchrone() => {
test("Il devrait revenir 4", () => {
attendre(somme(2,2)).être(4)
})
})
La décris mot-clé spécifie le groupe de tests et le test l'instruction spécifie le test spécifique. Si la valeur renvoyée par la fonction correspond à la valeur transmise à être, le test réussit.
Lors du test des points de terminaison de l'API, vous n'appelez pas une fonction, mais vous envoyez une requête à l'aide de SuperTest ou d'une autre bibliothèque cliente HTTP.
De retour au point de terminaison GET, créez un nouveau fichier appelé api.test.js. C'est ici que vous écrirez tous les tests de point de terminaison. Nommer le fichier de test avec un .test infix garantit que Jest le reconnaît comme un fichier de test.
Dans api.test.js, importez le supertest et définissez l'URL de base comme suit :
constante demande = exiger("supertest")
constante baseURL = "http ://hôte local: 3000"
Ensuite, créez le premier test dans le bloc describe :
décris("GET /todos", () => {
constante newTodo = {
identifiant: crypto.randomUUID(),
Objet: "Bois de l'eau",
complété: faux,
}
avant tout(asynchrone () => {
// configure la tâche
attendre la demande (baseURL).post("/todo").send (newTodo);
})
après tout(asynchrone () => {
attendre demande (baseURL).delete(`/à faire/${newTodo.id}`)
})
ce("devrait revenir 200", asynchrone () => {
constante réponse = attendre requête (baseURL).get("/todos");
attendre(réponse.statusCode).être(200);
attendre(réponse.corps.Erreur).être(nul);
});
ce("devrait retourner todos", asynchrone () => {
constante réponse = attendre requête (baseURL).get("/todos");
attendre (response.body.data.length >= 1).être(vrai);
});
});
Avant d'exécuter les tests, vous devrez définir les fonctions de configuration et de démontage. Ces fonctions rempliront le tableau todo avec un élément avant le test et supprimeront les données factices après chaque test.
Le code qui s'exécute avant tous les tests se trouve dans la fonction beforeAll(). Le code qui s'exécute après tous les tests se trouve dans la fonction afterAll().
Dans cet exemple, vous appuyez simplement sur les points de terminaison POST et DELETE pour chacun. Dans une application réelle, vous vous connecteriez probablement à une base de données fictive contenant les données de test.
Dans ce test, vous avez d'abord envoyé une requête au point de terminaison GET /todos et comparé la réponse renvoyée aux résultats attendus. Cette suite de tests réussira si la réponse a un Code d'état HTTP de 200, les données ne sont pas vides et le message d'erreur est nul.
Tester le point de terminaison POST /todo
Dans index.js, créez le point de terminaison POST /todo :
app.post("/todo", (req, res) => {
essayer {
constante { id, élément, terminé } = req.body ;
constante newTodo = {
identifiant,
Objet,
complété,
};
todos.pousser(nouveauTodo);
revenirres.statut(201).json({
données: tâches à effectuer,
Erreur: nul,
});
} attraper (Erreur) {
revenirres.statut(500).json({
Les données: nul,
erreur: erreur,
});
}
});
Dans ce test, vous devrez envoyer les détails de la tâche dans le corps de la requête à l'aide de la méthode send().
demande (URL de base).post("/todo").send (newTodo)
La requête POST /todo doit renvoyer un code d'état 201 et le tableau todos avec le nouvel élément ajouté à la fin. Voici à quoi pourrait ressembler le test :
décris("POST /à faire", () => {
constante newTodo = {
// faire
}
après tout(asynchrone () => {
attendre demande (baseURL).delete(`/à faire/${newTodo.id}`)
})
ce("devrait ajouter un élément au tableau todos", asynchrone () => {
constante réponse = attendre demande (baseURL).post("/todo").send(newTodo);
constante lastItem = réponse.body.data[response.body.data.length-1]
attendre(réponse.statusCode).être(201);
attendre(dernierélément.Objet).être(nouveauTodo["Objet"]);
attendre(dernierélément.complété).être(nouveauTodo["complété"]);
});
});
Ici, vous transmettez les données todo à la méthode send () en tant qu'argument. La réponse doit avoir un code d'état 201 et également contenir tous les éléments de tâche dans un objet de données. Pour tester si todo a été réellement créé, vérifiez si la dernière entrée dans les todos renvoyés correspond à celle que vous avez envoyée dans la requête.
Le point de terminaison PUT /todos/:id doit renvoyer l'élément mis à jour :
app.put("/todos/:id", (req, res) => {
essayer {
constante id = req.params.id
constante todo = todos.find((todo) => todo.id == id);
si(!à faire) {
jeterNouveauErreur("Todo introuvable")
}
todo.completed = req.body.completed ;
revenirres.statut(201).json({
données: à faire,
Erreur: nul,
});
} attraper (Erreur) {
revenirres.statut(500).json({
Les données: nul,
erreur: erreur,
});
}
});
Testez la réponse comme suit :
décris("Mettre à jour une tâche", () => {
constante newTodo = {
// faire
}
avant tout(asynchrone () => {
attendre la demande (baseURL).post("/todo").send (newTodo);
})
après tout(asynchrone () => {
attendre demande (baseURL).delete(`/à faire/${newTodo.id}`)
})
ce("devrait mettre à jour l'élément s'il existe", asynchrone () => {
constante réponse = attendre requête (URL de base).put(`/todos/${newTodo.id}`).envoyer({
complété: vrai,
});
attendre(réponse.statusCode).être(201);
attendre(réponse.corps.Les données.complété).être(vrai);
});
});
La valeur complétée dans le corps de la réponse doit être true. N'oubliez pas d'inclure l'identifiant de l'élément que vous souhaitez mettre à jour dans l'URL.
Testez le point de terminaison DELETE /todos/:id
Dans index.js, créez le point de terminaison DELETE. Il devrait renvoyer les données de la tâche sans l'élément supprimé.
app.delete("/todos/:id", (req, res) => {
essayer {
constante id = req.params.id
constante todo = todos[0]
si (à faire) {
todos.épissure(identifiant, 1)
}
revenirres.statut(200).json({
données: tâches à effectuer,
Erreur: nul,
});
} attraper (Erreur) {
revenirres.statut(500).json({
Les données: nul,
erreur: erreur,
});
}
});
Pour tester le point de terminaison, vous pouvez vérifier si l'élément supprimé existe toujours dans les données renvoyées :
décris("Supprimer une tâche", () => {
constante newTodo = {
// faire
}
avant tout(asynchrone () => {
attendre la demande (baseURL).post("/todo").send (newTodo);
})
ce("devrait supprimer un élément", asynchrone () => {
constante réponse = attendre demande (baseURL).delete(`/todos/${newTodo.id}`);
constante todos = réponse.corps.données
constante existe = todos.find (todo => {
newTodo.id == todoId
})
attendre (existe).toBe(indéfini)
});
});
Les données renvoyées par le point de terminaison DELETE ne doivent pas contenir l'élément supprimé. Étant donné que les éléments renvoyés se trouvent dans un tableau, vous pouvez utiliser Array[id] pour vérifier si l'API a correctement supprimé l'élément. Le résultat devrait être faux.
Création d'API REST
Dans cet article, vous avez appris à tester une API Express Rest à l'aide de l'API Jest. Vous avez écrit des tests pour les requêtes HTTP GET, PUT, POST et DELETE et vous avez vu comment envoyer des données au point de terminaison dans l'URL et la requête. Vous devriez être en mesure d'appliquer ces connaissances lors du test de votre propre API Rest.