Un guide de test pour Express avec simulation/stubbing de requêtes et de réponses en utilisant Jest ou sinon · Coder avec Hugo (2024)

/ #Exprimer#nœud

Curieux de connaître les fonctionnalités avancées de test de Jest ?

Faites passer vos tests JavaScript au niveau supérieur en apprenant les tenants et les aboutissants de Jest, la meilleure bibliothèque de tests JavaScript.

Obtenez "The Jest Handbook" (100 pages)

Je veux ceci

Pour tester un gestionnaire Express, il est utile de savoir comment réussir à simuler/stub ledemandeetréponseobjets. Les exemples suivants seront écrits à la fois en utilisant Jest et sinon (fonctionnant en AVA).

La raison en est la suivante. Jest est un framework de test « tout-en-un » très populaire. Sinon est l'un des « espions, stubs et simulations de tests autonomes pour JavaScript » les plus populaires qui « fonctionne avec n'importe quel framework de tests unitaires ».

L'approche détaillée dans cet article portera sur la manière de tester les gestionnaires indépendamment de l'instance de l'application Express en les appelant directement avec une requête simulée (demande) et la réponse (rés) objets. Il ne s’agit que d’une seule approche pour tester les gestionnaires et middleware Express. L'alternative consiste à lancer le serveur Express (idéalement en mémoire à l'aide de SuperTest). J'explique plus en détail comment y parvenir"Tester une application Express avec SuperTest, Moxios et Jest".

L'un des grands progrès conceptuels pour tester les applications Express avec une requête/réponse simulée est de comprendre comment simuler une API chaînée, par exemple.res.status(200).json({ foo: 'bar' }).

Ceci est réalisé en renvoyant lerésinstance de chacune de ses méthodes :

const réponse simulée = () => { const rés = {} ; // remplace ce qui suit () => res // avec votre stub/mock de fonction de votre choix // s'assurant qu'ils renvoient toujours `res` rés.statut = () => rés; rés.json = () => rés; retour rés;} ;

Voir le référentiel avec des exemples et l'application de travail surgithub.com/HugoDF/mock-express-request-response.

Table des matières:

Table des matières

Stubs et simulations : Jest.fn vs sinon

est.fnetsinon.stubont le même rôle. Ils renvoient tous deux un mock/stub pour une fonction. Cela signifie simplement une fonction qui rappelle des informations sur ses appels, par exemple. combien de fois et avec quels arguments il a été appelé.

La maquette Jest est étroitement intégrée au reste du framework. Cela signifie que nous pouvons avoir des assertions qui ressemblent à ce qui suit :

test('jest.fn rappelle comment il a été appelé', () => { const se moquer = Est.fn(); se moquer('un', 'b', 'c'); attendre(se moquer).toHaveBeenCalledTimes(1); attendre(se moquer).toHaveBeenCalledWith('un', 'b', 'c');});

Sinon est « juste » une bibliothèque d'espions/stubs/mocks, cela signifie que nous avons besoin d'un exécuteur de test séparé, l'exemple suivant est équivalent au précédent de Jest mais écrit en utilisant AVA :

const test = exiger('ava');const sinon = exiger('sinon');test('sinon.stub rappelle comment il a été appelé', t => { const se moquer = sinon.bout(); se moquer('un', 'b', 'c'); t.vrai(se moquer.appelé); t.vrai(se moquer.appeléAvec('un', 'b', 'c'));});

Se moquer/stubbing d'une API chaînée : réponse express

L’API Express User-Land est basée sur un middleware. Un middleware qui prend une requête (généralement appelédemande), une réponse (généralement appeléerés) et un next (appeler le middleware suivant) comme paramètres.

Un « gestionnaire de route » est un middleware qui a tendance à ne pas appelersuivant, cela entraîne généralement l'envoi d'une réponse.

Un exemple de gestionnaires de routes est le suivant (dans express-handlers.js).

Dans cet exempledemande de sessionest généré parsessions-client, un middleware de Mozilla qui définit un cookie crypté sur le client (à l'aide d'unSet-Cookie). Cela dépasse la portée de cet article. À toutes fins utiles, nous pourrions accéder/écrire à tout autre ensemble de propriétés de requête/réponse.

asynchrone fonction Se déconnecter(demande, rés) { demande.session.données = nul; retour rés.statut(200).json();}asynchrone fonction vérifierAuth(demande, rés) { si (!demande.session.données) { retour rés.statut(401).json(); } const { nom d'utilisateur } = demande.session.données; retour rés.statut(200).json({ nom d'utilisateur });}module.exportations = { Se déconnecter, vérifierAuth} ;

Ils sont consommés en étant « montés » sur une application Express (application) instance (dans app.js) :

const exprimer = exiger('exprimer');const application = exprimer();const { Se déconnecter, vérifierAuth } = exiger('./express-handlers.js');application.obtenir('/session', vérifierAuth);application.supprimer('/session', Se déconnecter);

Pour que le code ci-dessus fonctionne de manière intégrée, nous devons égalementapp.uselesessions-clientpaquet comme ça. Notez que leNom du cookieest important puisque c'est la propriété sous laquelle la session est définie sur ledemandeobjet.

Nous ajoutons également leexpress.jsonmiddleware (Express 4.16+), qui fonctionne comme celui de l'analyseur de corps.json()option c'est à dire. il analyse les corps JSON et stocke la sortie danscorps requis.

const exprimer = exiger('exprimer');const application = exprimer();const session = exiger('sessions-client');application.utiliser(exprimer.json());application.utiliser(session({ secrète: processus.env.SESSION_SECRET || 'mon-super-secret', Nom du cookie: 'session', durée: 60 * 60 * 1000 // 1 heure}));const { Se déconnecter, vérifierAuth } = exiger('./express-handlers.js');application.obtenir('/session', vérifierAuth);application.supprimer('/session', Se déconnecter);

Demande de moquerie/stubbing (une simple requête Express) avec Jest ou sinon

Une fonction mockRequest doit renvoyer un objet compatible avec la requête, qui est un simple objet JavaScript. Il pourrait ressembler à ce qui suit, en fonction des propriétés dedemandele code testé utilise. Notre code accède uniquementreq.session.data, ça veut dire qu'il attenddemandeavoir unsessionpropriété qui est un objet afin qu'il puisse tenter d'accéder aureq.session.datapropriété.

const mockRequest = (données de session) => { retour { session: { données: données de session }, } ;} ;

Puisque ce qui précède ne concerne que les données, il n'y a aucune différence entre s'en moquer dans Jest ou utiliser sinon et le lanceur de test de votre choix (Mocha, AVA, tape, Jasmine…).

Résolution moqueuse/stubbing (une simple réponse express) avec Jest

Une fonction mockResponse ressemblerait à ce qui suit, notre code testé appelle uniquementstatutetjsonles fonctions. Le problème que nous rencontrons est que les appels s’enchaînent. Cela signifie questatut,jsonet autrerés(Réponse express) renvoient lerésobjet lui-même.

Cela signifie qu'idéalement, notre simulation se comporterait de la même manière :

const réponse simulée = () => { const rés = {} ; rés.statut = Est.fn().mockReturnValue(rés); rés.json = Est.fn().mockReturnValue(rés); retour rés;} ;

Nous exploitonsest.fnc'estmockReturnValueméthode pour définir la valeur de retour des deuxstatutetjsonà l'instance de réponse fictive (rés) ils sont prêts.

Résolution moqueuse/stubbing (une simple réponse express) avec sinon

Le sinon équivalent à ce qui précède (avec une explication similaire) suit. Avec sinon, nous devons explicitementexigercar il s'agit d'une bibliothèque autonome (c'est-à-dire non injectée par des frameworks de test).

Les talons Sinon ont unRetourméthode qui se comporte comme lamockReturnValueMéthode de simulation de plaisanterie. Il définit la valeur de retour du stub.

Lestatutetjsonméthodes sur notre instance de réponse fictive (rés) renvoie l'instance de réponse (rés) lui-même.

const sinon = exiger('sinon');const réponse simulée = () => { const rés = {} ; rés.statut = sinon.bout().Retour(rés); rés.json = sinon.bout().Retour(rés); retour rés;} ;

Tester un gestionnaire qui lit depuisdemandeet envoie unrésen utilisant status et json()

LevérifierAuthle gestionnaire lit à partir dedemandeet envoie unrésen utilisantstatut()etjson().

Il contient la logique suivante, sisession.datan'est pas défini, la session n'est pas définie et donc l'utilisateur n'est pas authentifié, il envoie donc un401 Non autoriséstatut avec un corps JSON vide. Sinon, il reflète la partie du contenu de la session (juste lenom d'utilisateur) en réponse JSON avec un code d'état 200.

Voici le code testé (dans express-handlers.js) :

asynchrone fonction vérifierAuth(demande, rés) { si (!demande.session.données) { retour rés.statut(401).json(); } const { nom d'utilisateur } = demande.session.données; retour rés.statut(200).json({ nom d'utilisateur });}

Nous devons tester deux chemins : l’un menant à un 401 et l’autre menant à un 200.

Voir un instantané de ce code sur GitHubgithub.com/HugoDF/mock-express-request-response/releases/tag/check-auth-tests(cliquez sur le commit sha pour le diff pour ce changement de version).

En utilisant lemockRequestetréponse simuléenous avons défini précédemment, nous définirons une requête qui n'a pas de données de session (pour 401) et qui a des données de session contenant le nom d'utilisateur (pour 200). Ensuite, nous vérifierons celastatut requisest appelé avec 401 et 200 respectivement. Dans le cas 200, nous vérifierons également queres.jsonest appelé avec la bonne charge utile ({ nom d'utilisateur }).

Dans Jest (voir express-handlers.jest-test.js) :

décrire('vérifierAuth', () => { test('devrait 401 si les données de session ne sont pas définies', asynchrone () => { const demande = mockRequest(); const rés = réponse simulée(); attendre vérifierAuth(demande, rés); attendre(rés.statut).toHaveBeenCalledWith(401); }); test('devrait 200 avec le nom d'utilisateur de la session si les données de session sont définies', asynchrone () => { const demande = mockRequest({ nom d'utilisateur: 'hugo' }); const rés = réponse simulée(); attendre vérifierAuth(demande, rés); attendre(rés.statut).toHaveBeenCalledWith(200); attendre(rés.json).toHaveBeenCalledWith({ nom d'utilisateur: 'hugo' }); });});

Les mêmes tests utilisant sinon + AVA (dans express-handlers.sinon-test.js) :

test('checkAuth > devrait 401 si les données de session ne sont pas définies', asynchrone (t) => { const demande = mockRequest(); const rés = réponse simulée(); attendre vérifierAuth(demande, rés); t.vrai(rés.statut.appeléAvec(401));});test('checkAuth > devrait 200 avec le nom d'utilisateur de la session si les données sont définies', asynchrone (t) => { const demande = mockRequest({ nom d'utilisateur: 'hugo' }); const rés = réponse simulée(); attendre vérifierAuth(demande, rés); t.vrai(rés.statut.appeléAvec(200)); t.vrai(rés.json.appeléAvec({ nom d'utilisateur: 'hugo' }));});

Voir un instantané de ce code sur GitHubgithub.com/HugoDF/mock-express-request-response/releases/tag/check-auth-tests(cliquez sur le commit sha pour le diff pour ce changement de version).

Tester un gestionnaire qui écrit dansdemandeet envoie unrésen utilisant status et json()

LeSe déconnecterle gestionnaire écrit dans req (il définitreq.session.dataànul) et envoie une réponse en utilisantres.statutetres.json. Voici le code en cours de test.

asynchrone fonction Se déconnecter(demande, rés) { demande.session.données = nul; retour rés.statut(200).json();}

Il n'a pas de logique de branchement, mais nous devrions le testersession.dataest réinitialisé et une réponse est envoyée dans 2 tests distincts. Voir un instantané de ce code sur GitHubgithub.com/HugoDF/mock-express-request-response/releases/tag/logout-tests(cliquez sur le commit sha pour le diff pour ce changement de version).

En plaisantant, avec lemockRequestetréponse simuléefonctions (dans express-handlers.jest-test.js) :

décrire('Se déconnecter', () => { test('devrait définir session.data sur null', asynchrone () => { const demande = mockRequest({ nom d'utilisateur: 'hugo' }); const rés = réponse simulée(); attendre Se déconnecter(demande, rés); attendre(demande.session.données).êtreNull(); }); test('devrait 200', asynchrone () => { const demande = mockRequest({ nom d'utilisateur: 'hugo' }); const rés = réponse simulée(); attendre Se déconnecter(demande, rés); attendre(rés.statut).toHaveBeenCalledWith(200); });});

Dans AVA + sinon en utilisant les fonctions mockRequest et mockResponse (dans express-handlers.sinon-test.js) :

test('déconnexion> devrait définir session.data sur null', asynchrone (t) => { const demande = mockRequest({ nom d'utilisateur: 'hugo' }); const rés = réponse simulée(); attendre Se déconnecter(demande, rés); t.est(demande.session.données, nul);});test('déconnexion > devrait 200', asynchrone (t) => { const demande = mockRequest({ nom d'utilisateur: 'hugo' }); const rés = réponse simulée(); attendre Se déconnecter(demande, rés); t.vrai(rés.statut.appeléAvec(200));});

Voir un instantané de ce code sur GitHubgithub.com/HugoDF/mock-express-request-response/releases/tag/logout-tests(cliquez sur le commit sha pour le diff pour ce changement de version).

Un scénario moqueur de demande/réponse de gestionnaire complexe : une demande de connexion avec un corps

Notre gestionnaire de connexion fait le gros du travail dans l’application. C'est dedansexpress-handlers.jset contient la logique suivante.

Le gestionnaire de connexion vérifie d'abord que le contenu decorps requiset 400s si l'un d'eux manque (ce seront nos 2 premiers tests).

Le gestionnaire de connexion tente ensuite deobtenirUtilisateurpour le nom d'utilisateur donné, s'il n'y a pas un tel utilisateur, c'est 401 (ce sera notre 3ème test).

Ensuite, le gestionnaire de connexion compare le mot de passe de la requête avec la version hachée/salée provenant deobtenirUtilisateursortie, si cette comparaison échoue, c'est 401 (ce sera notre 4ème test).

Enfin, si le nom d'utilisateur/mot de passe sont valides pour un utilisateur, le gestionnaire de connexion définit session.data sur{ nom d'utilisateur }et envoie une réponse 201 (ce sera notre 5ème test).

Le dernier test (que je n'ai pas implémenté) qui aurait du sens est de vérifier que le gestionnaire envoie un 500 si une erreur survient lors de son exécution (par exemple.obtenirUtilisateurlance).

Voir un instantané du code sur GitHubgithub.com/HugoDF/mock-express-request-response/releases/tag/login-tests(cliquez sur le commit sha pour le diff pour ce changement de version).

Les fonctions de connexion sont les suivantes, pour des raisons de lisibilité, j'ai omisobtenirUtilisateur.obtenirUtilisateurest implémenté dans tous les cas sous la forme d'une recherche de tableau codée en dur, alors que dans votre application, il s'agira d'une base de données ou d'un appel d'API (sauf si vous utilisez oAuth).

const bcrypt = exiger('bcrypt');asynchrone fonction se connecter(demande, rés) { essayer { const { nom d'utilisateur, mot de passe } = demande.corps; si (!nom d'utilisateur || !mot de passe) { retour rés.statut(400).json({ message: 'le nom d'utilisateur et le mot de passe sont requis' }); } const utilisateur = obtenirUtilisateur(nom d'utilisateur); si (!utilisateur) { retour rés.statut(401).json({ message: "Aucun utilisateur avec le nom d'utilisateur correspondant" }); } si (!(attendre bcrypt.comparer(mot de passe, utilisateur.mot de passe))) { retour rés.statut(401).json({ message: 'Mauvais mot de passe' }); } demande.session.données = { nom d'utilisateur } ; retour rés.statut(201).json(); } attraper (e) { console.erreur(`Erreur lors de la connexion de "${demande.corps.nom d'utilisateur}" :${e.empiler}`); rés.statut(500).json({ message: e.message }); }}

Il se consomme, en étant « monté » sur l’application Express enapp.js:

application.poste('/session', se connecter);

Pour pouvoir tester la fonction de connexion, nous devons étendre lamockRequestfonction, elle renvoie toujours un simple objet JavaScript donc il n'y a pas de différence entre notre version Jest et AVA + sinon :

const mockRequest = (données de session, corps) => ({ session: { données: données de session }, corps,});

Voir un instantané du code sur GitHubgithub.com/HugoDF/mock-express-request-response/releases/tag/login-tests(cliquez sur le commit sha pour le diff pour ce changement de version).

Tests pour le gestionnaire de connexion utilisant dans Jest

Note:Il y a un grand mur de code entrant.

Vous pouvez passer ausinon + AVA versionsi c'est ce que vous souhaitez utiliserce lien

Passer auMiddleware et en-têtes request.getsection utilisantce lien.

Pour tester minutieusem*nt ce gestionnaire Express, il faut quelques tests supplémentaires mais fondamentalement les mêmes principes que dans levérifierAuthetSe déconnectergestionnaires.

Les tests ressemblent à ce qui suit (dans express-handlers.jest-test.js) :

décrire('se connecter', () => { test('devrait 400 si le nom d'utilisateur est absent du corps', asynchrone () => { const demande = mockRequest( {}, { mot de passe: 'chef' } ); const rés = réponse simulée(); attendre se connecter(demande, rés); attendre(rés.statut).toHaveBeenCalledWith(400); attendre(rés.json).toHaveBeenCalledWith({ message: 'le nom d'utilisateur et le mot de passe sont requis' }); }); test('devrait 400 si le mot de passe est absent du corps', asynchrone () => { const demande = mockRequest( {}, { nom d'utilisateur: 'hugo' } ); const rés = réponse simulée(); attendre se connecter(demande, rés); attendre(rés.statut).toHaveBeenCalledWith(400); attendre(rés.json).toHaveBeenCalledWith({ message: 'le nom d'utilisateur et le mot de passe sont requis' }); }); test('devrait 401 avec un message si l'utilisateur avec le nom d'utilisateur transmis n'existe pas', asynchrone () => { const demande = mockRequest( {}, { nom d'utilisateur: 'Hugo Boss', mot de passe: 'chef' } ); const rés = réponse simulée(); attendre se connecter(demande, rés); attendre(rés.statut).toHaveBeenCalledWith(401); attendre(rés.json).toHaveBeenCalledWith({ message: "Aucun utilisateur avec le nom d'utilisateur correspondant" }); }); test('devrait 401 avec un message si le mot de passe transmis ne correspond pas au mot de passe stocké', asynchrone () => { const demande = mockRequest( {}, { nom d'utilisateur: 'invité', mot de passe: 'pas-bon-mot de passe' } ); const rés = réponse simulée(); attendre se connecter(demande, rés); attendre(rés.statut).toHaveBeenCalledWith(401); attendre(rés.json).toHaveBeenCalledWith({ message: 'Mauvais mot de passe' }); }); test('devrait 201 et définir session.data avec le nom d'utilisateur si l'utilisateur existe et le bon mot de passe fourni', asynchrone () => { const demande = mockRequest( {}, { nom d'utilisateur: 'invité', mot de passe: 'patron invité' } ); const rés = réponse simulée(); attendre se connecter(demande, rés); attendre(rés.statut).toHaveBeenCalledWith(201); attendre(rés.json).avoir été appelé(); attendre(demande.session.données).égaler({ nom d'utilisateur: 'invité', }); });});

Voir un instantané du code sur GitHubgithub.com/HugoDF/mock-express-request-response/releases/tag/login-tests(cliquez sur le commit sha pour le diff pour ce changement de version).

Tests du gestionnaire de connexion en utilisant AVA + sinon

Note:Il y a (un autre) grand mur de code entrant.

Vous pouvez retourner auIl existe une versionsi c'est ce que vous souhaitez utiliserce lien

Passer auMiddleware et en-têtes request.getsection utilisantce lien.

Encore une fois, il n'y a rien de fondamentalement nouveau dans ces tests, ils sont juste plus denses et plus proches de ce que vous feriez dans une application réelle, ils sont les suivants (dans express-handlers.sinon-test.js) :

Voir un instantané du code sur GitHubgithub.com/HugoDF/mock-express-request-response/releases/tag/login-tests(cliquez sur le commit sha pour le diff pour ce changement de version).

test('login > devrait 400 si le nom d'utilisateur est absent du corps', asynchrone (t) => { const demande = mockRequest( {}, { mot de passe: 'chef' } ); const rés = réponse simulée(); attendre se connecter(demande, rés); t.vrai(rés.statut.appeléAvec(400)); t.vrai(rés.json.appeléAvec({ message: 'le nom d'utilisateur et le mot de passe sont requis' }));});test('devrait 400 si le mot de passe est absent du corps', asynchrone (t) => { const demande = mockRequest( {}, { nom d'utilisateur: 'hugo' } ); const rés = réponse simulée(); attendre se connecter(demande, rés); t.vrai(rés.statut.appeléAvec(400)); t.vrai(rés.json.appeléAvec({ message: 'le nom d'utilisateur et le mot de passe sont requis' }));});test('devrait 401 avec un message si l'utilisateur avec le nom d'utilisateur transmis n'existe pas', asynchrone (t) => { const demande = mockRequest( {}, { nom d'utilisateur: 'Hugo Boss', mot de passe: 'chef' } ); const rés = réponse simulée(); attendre se connecter(demande, rés); t.vrai(rés.statut.appeléAvec(401)); t.vrai(rés.json.appeléAvec({ message: "Aucun utilisateur avec le nom d'utilisateur correspondant" }));});test('devrait 401 avec un message si le mot de passe transmis ne correspond pas au mot de passe stocké', asynchrone (t) => { const demande = mockRequest( {}, { nom d'utilisateur: 'invité', mot de passe: 'pas-bon-mot de passe' } ); const rés = réponse simulée(); attendre se connecter(demande, rés); t.vrai(rés.statut.appeléAvec(401)); t.vrai(rés.json.appeléAvec({ message: 'Mauvais mot de passe' }));});test('devrait 201 et définir session.data avec le nom d'utilisateur si l'utilisateur existe et le bon mot de passe fourni', asynchrone (t) => { const demande = mockRequest( {}, { nom d'utilisateur: 'invité', mot de passe: 'patron invité' } ); const rés = réponse simulée(); attendre se connecter(demande, rés); t.vrai(rés.statut.appeléAvec(201)); t.vrai(rés.json.appelé); t.profondÉgal( demande.session.données, { nom d'utilisateur: 'invité' } );});

Voir un instantané du code sur GitHubgithub.com/HugoDF/mock-express-request-response/releases/tag/login-tests(cliquez sur le commit sha pour le diff pour ce changement de version).

Tester un middleware et se moquer des en-têtes Express request.get

Un autre scénario dans lequel vous souhaiterez peut-être simuler/stub les objets de requête et de réponse Express est celui du test d'une fonction middleware.

Le test du middleware est subtilement différent. De nombreux middlewares ont des conditions dans lesquelles ils ne font rien (ils appellent simplementsuivant()). Un middleware Express doit toujours appelersuivant()(son 3ème paramètre) ou envoyer une réponse.

Voici un exemple de middleware qui permet l'authentification à l'aide d'une clé API dans unAutorisationen-tête du formatPorteur {API_KEY}.

Au-delà des différences entre middleware et gestionnaire,en-têteAuthutilise égalementreq.get(), qui est utilisé pour obtenir les en-têtes de la requête Express.

j'ai omisapiKeyToUseretisApiKey.apiKeyToUserest juste une recherche d'apiKeys vers les noms d'utilisateur. Dans une application réelle, il s'agirait d'une recherche dans une base de données, un peu comme ce qui remplaceraitobtenirUtilisateurdans lese connectercode.

fonction en-têteAuth(demande, rés, suivant) { si (demande.session.données) { retour suivant() } const authentificationEn-tête = demande.obtenir('autorisation') si(!authentificationEn-tête) { retour suivant() } const clé API = authentificationEn-tête .remplacer('Porteur', '') .garniture(); si (!isApiKey(clé API)) { retour suivant() } demande.session.données = { nom d'utilisateur: apiKeyToUser[clé API] } ; suivant();}

Voir un instantané du code sur GitHubgithub.com/HugoDF/mock-express-request-response/releases/tag/middleware-header-tests(cliquez sur le commit sha pour le diff pour ce changement de version).

Mise à jour de mockRequest pour prendre en charge l'accès aux en-têtes

Voici une version différente de mockRequest, c'est toujours un simple objet JavaScript, et il se moquereq.getjuste assez pour réussir les tests :

const mockRequest = (en-tête d'authentification, données de session) => ({ obtenir(nom) { si (nom === 'autorisation') retour en-tête d'authentification retour nul }, session: { données: données de session }});

Tester un middleware qui accède aux en-têtes avec Jest

La plupart des tests vérifient que rien ne change sur la session pendant l'exécution du middleware car il présente de nombreuses conditions de court-circuit.

Notez comment nous transmettons une fonction sans opération() => {}comme 3ème paramètre (qui estsuivant).

décrire('en-têteAuthMiddleware', () => { test('doit définir req.session.data si la clé API est en autorisation et est valide', asynchrone () => { const demande = mockRequest('76b1e728-1c14-43f9-aa06-6de5cbc064c2'); const rés = réponse simulée(); attendre headerAuthMiddleware(demande, rés, () => {}); attendre(demande.session.données).égaler({ nom d'utilisateur: 'hugo' }); }); test('ne devrait rien faire si req.session.data est déjà défini', asynchrone () => { const demande = mockRequest('76b1e728-1c14-43f9-aa06-6de5cbc064c2', { nom d'utilisateur: 'invité' }); const rés = réponse simulée(); attendre headerAuthMiddleware(demande, rés, () => {}); attendre(demande.session.données).égaler({ nom d'utilisateur: 'invité' }); }); test('ne devrait rien faire si l'en-tête d'autorisation n'est pas présent', asynchrone () => { const demande = mockRequest(indéfini); const rés = réponse simulée(); attendre headerAuthMiddleware(demande, rés, () => {}); attendre(demande.session.données).être indéfini(); }); test('ne devrait rien faire si la clé API n'est pas valide', asynchrone () => { const demande = mockRequest('clé API invalide'); const rés = réponse simulée(); attendre headerAuthMiddleware(demande, rés, () => {}); attendre(demande.session.données).être indéfini(); });});

Voir un instantané du code sur GitHubgithub.com/HugoDF/mock-express-request-response/releases/tag/middleware-header-tests(cliquez sur le commit sha pour le diff pour ce changement de version).

Tester un middleware qui accède aux en-têtes en utilisant AVA + sinon

La plupart des tests vérifient que rien ne change sur la session pendant l'exécution du middleware car il présente de nombreuses conditions de court-circuit.

Notez comment nous transmettons une fonction sans opération() => {}comme 3ème paramètre (qui estsuivant).

test('doit définir req.session.data si la clé API est en autorisation et est valide', asynchrone (t) => { const demande = mockRequest('76b1e728-1c14-43f9-aa06-6de5cbc064c2'); const rés = réponse simulée(); attendre headerAuthMiddleware(demande, rés, () => {}); t.profondÉgal( demande.session.données, { nom d'utilisateur: 'hugo' } );});test('ne devrait rien faire si req.session.data est déjà défini', asynchrone (t) => { const demande = mockRequest('76b1e728-1c14-43f9-aa06-6de5cbc064c2', { nom d'utilisateur: 'invité' }); const rés = réponse simulée(); attendre headerAuthMiddleware(demande, rés, () => {}); t.profondÉgal( demande.session.données, { nom d'utilisateur: 'invité' } );});test('ne devrait rien faire si l'en-tête d'autorisation n'est pas présent', asynchrone (t) => { const demande = mockRequest(indéfini); const rés = réponse simulée(); attendre headerAuthMiddleware(demande, rés, () => {}); t.est(demande.session.données, indéfini);});test('ne devrait rien faire si la clé API n'est pas valide', asynchrone (t) => { const demande = mockRequest('clé API invalide'); const rés = réponse simulée(); attendre headerAuthMiddleware(demande, rés, () => {}); t.est(demande.session.données, indéfini);});

Voir un instantané du code sur GitHubgithub.com/HugoDF/mock-express-request-response/releases/tag/middleware-header-tests(cliquez sur le commit sha pour le diff pour ce changement de version).

Clés pour tester les gestionnaires et middleware Express

Il existe quelques clés pour tester efficacement Express de la manière décrite dans cet article.

Tout d’abord, il faut comprendre ce que fait le code. C'est plus difficile qu'il n'y paraît. Tester en JavaScript consiste en grande partie à comprendre JavaScript, un peu à tester les outils et un peu à comprendre les outils utilisés dans l'application testée. Afin de se moquer des valeurs de retour de l’outil avec le bon type de données.

Tous les tests du post se résument à comprendre ce quedemande,résetsuivantsont (un objet, un objet et une fonction). Quelles propriétés ils ont/peuvent avoir, comment ces propriétés sont utilisées et s'il s'agit d'une fonction ou d'un objet.

Il ne s’agit que d’une seule approche pour tester les gestionnaires et middleware Express. L'alternative consiste à lancer le serveur Express (idéalement en mémoire à l'aide de SuperTest). J'explique plus en détail comment y parvenir"Tester une application Express avec SuperTest, Moxios et Jest"

Chris Barbalis

Obtenez le manuel Jest (100 pages)

Faites passer vos tests JavaScript au niveau supérieur en apprenant les tenants et les aboutissants de Jest, la meilleure bibliothèque de tests JavaScript.

En savoir plus

ou

Rejoignez des milliers de développeurs qui découvrent Node.js et JavaScript de niveau entreprise

Un guide de test pour Express avec simulation/stubbing de requêtes et de réponses en utilisant Jest ou sinon · Coder avec Hugo (2024)

FAQs

What is Sinon used for? ›

Sinon JS is a popular JavaScript library that lets you replace complicated parts of your code that are hard to test for “placeholders,” so you can keep your unit tests fast and deterministic, as they should be.

How to mock express request and response in jest? ›

Mock Express request/response with Jest or sinon
  1. Clone the repository.
  2. Run npm install.
  3. Run npm start (to start the application locally) or npm t to run the tests.
Jan 5, 2023

What is the generic term for an object or procedure you use to replace a real object or procedure that is hard to test? ›

The generic term he uses is a Test Double (think stunt double). Test Double is a generic term for any case where you replace a production object for testing purposes.

How to mock response in jest? ›

To mock a function's return value in Jest, you first need to import all named exports from a module, then use mockReturnValue on the imported function. You can use the * as <alias> inside an import statement to import all named exports. Then, you need to chain mockReturnValue off of jest.

What does Sinon call her gun? ›

Known as Sinon ingame, her main weapon is the «PGM Ultima Ratio Hecate II» sniper rifle, which she earned after defeating a monster in a dungeon.

What is Sinon to kirito? ›

In all of their interactions post-GGO they seem to have more of a brother-sister, teasing, type relationship than Kirito does with the rest of the girls.

How to mock API response for testing? ›

Enable response mocking
  1. Select the API you created in Create a test API.
  2. In the window on the right, ensure that the Design tab is selected.
  3. Select the test operation that you added.
  4. In the Inbound processing window, select + Add policy.
  5. Select Mock responses from the gallery.
Jan 13, 2023

How do you check if mocked method was called Jest? ›

To check if a function was called correctly with Jest we use the expect() function with specific matcher methods to create an assertion. We can use the toHaveBeenCalledWith() matcher method to assert the arguments the mocked function has been called with.

How to use mock function Jest? ›

There are two ways to mock functions: creating a mock function in test code or writing a manual mock to override a module dependency. We can create a mock function using Jest. fn(), we can mock a module using Jest. mock().

What is the difference between clear all mocks and reset all mocks? ›

The clear and reset methods cleans the internal state of the mock so our expect on how many times the mock was called are always 1 . The difference between those two is that the reset destroys also our mock implementation and replaces it with function with no return value.

How to mock a REST API call? ›

Mocking REST API
  1. Import rest from the msw package:
  2. Create request handlers by calling rest[METHOD] and providing a request path:
  3. Provide response resolvers to the previously defined request handlers:

How do I reset my mock before each test Jest? ›

Resetting mock implementation

This can be useful when you want to change the mock function's behavior between tests. To reset a mock function's implementation, you can use the mockFn. mockImplementation() function with no arguments. This will reset the mock function's implementation to its default behavior.

What is the difference between Sinon and jest? ›

Jest: Painless JavaScript Unit Testing. Jest provides you with multiple layers on top of Jasmine; SinonJS: Standalone test spies, stubs and mocks for JavaScript. It is a really helpful library when you want to unit test your code.

What is Sinon vs Mocha vs Chai? ›

js code: Mocha is a testing framework for describing and running tests. Chai is an assertion library. Sinon is a mocking and stubbing library.

What are the advantages of the Sinon JS framework? ›

What are the advantages of Sinon. JS framework? (2 correct answers) It provides support for Spies, stubs and mocks It supplies higher level test doubles for timers and AJAX requests It enables test-driven environment It can be used with any Javascript unit test framework.

What is the difference between stub and spy Sinon? ›

Spy = FuncInfoCollector + can create new function + It can wrap a function that already exists in the system under test. Spy is a good choice whenever the goal of a test is to verify something happened. Stub = spy + it stubs the original function ( can be used to change behaviour of original function).

References

Top Articles
Latest Posts
Article information

Author: Carlyn Walter

Last Updated:

Views: 5819

Rating: 5 / 5 (50 voted)

Reviews: 89% of readers found this page helpful

Author information

Name: Carlyn Walter

Birthday: 1996-01-03

Address: Suite 452 40815 Denyse Extensions, Sengermouth, OR 42374

Phone: +8501809515404

Job: Manufacturing Technician

Hobby: Table tennis, Archery, Vacation, Metal detecting, Yo-yoing, Crocheting, Creative writing

Introduction: My name is Carlyn Walter, I am a lively, glamorous, healthy, clean, powerful, calm, combative person who loves writing and wants to share my knowledge and understanding with you.