DEV Community

Cover image for Nock : Mocker les requêtes HTTP en Node.js (avec une alternative sans code)
Antoine Laurent
Antoine Laurent

Posted on • Originally published at apidog.com

Nock : Mocker les requêtes HTTP en Node.js (avec une alternative sans code)

Si vos tests Node.js échouent parce qu’une API tierce est hors service, lente ou limitée par un quota, le problème n’est pas forcément votre code : c’est votre dépendance réseau. Pour rendre vos tests unitaires rapides et déterministes, simulez la couche HTTP avec nock. Ce guide montre comment l’utiliser dans un test Node.js, comment vérifier les cas d’erreur, et quand passer à un serveur de maquette partagé plutôt qu’à une interception locale. Pour la référence complète, consultez le dépôt GitHub de nock.

Essayez Apidog aujourd’hui

Qu’est-ce que nock ?

nock est une bibliothèque Node.js qui intercepte les requêtes HTTP sortantes pendant l’exécution des tests.

Concrètement, nock surcharge les modules natifs http et https de Node.js. Quand votre code appelle une API externe avec fetch, axios, got, node-fetch ou un autre client basé sur http/https, nock peut remplacer l’appel réel par une réponse définie dans votre test.

Résultat :

  • aucun appel réseau réel ;
  • pas de dépendance à l’état d’une API tierce ;
  • des tests plus rapides ;
  • des scénarios d’erreur faciles à reproduire ;
  • une suite de tests plus stable.

Installez nock comme dépendance de développement :

npm install --save-dev nock
Enter fullscreen mode Exit fullscreen mode

ou avec pnpm :

pnpm add -D nock
Enter fullscreen mode Exit fullscreen mode

Exemple minimal avec nock

Supposons que vous ayez une fonction qui récupère un utilisateur depuis une API externe.

// user-service.js
export async function getUser(id) {
  const res = await fetch(`https://api.example.com/users/${id}`);

  if (!res.ok) {
    throw new Error(`Request failed: ${res.status}`);
  }

  return res.json();
}
Enter fullscreen mode Exit fullscreen mode

Voici un test qui intercepte l’appel HTTP avec nock :

// user-service.test.js
import nock from 'nock';
import { getUser } from './user-service.js';

test('returns the user when the API responds', async () => {
  nock('https://api.example.com')
    .get('/users/42')
    .reply(200, { id: 42, name: 'Ada Lovelace' });

  const user = await getUser(42);

  expect(user).toEqual({ id: 42, name: 'Ada Lovelace' });
});
Enter fullscreen mode Exit fullscreen mode

Ce test se lit ainsi :

nock('https://api.example.com')
Enter fullscreen mode Exit fullscreen mode

Définit l’hôte à intercepter.

.get('/users/42')
Enter fullscreen mode Exit fullscreen mode

Indique la méthode HTTP et le chemin attendus.

.reply(200, { id: 42, name: 'Ada Lovelace' })
Enter fullscreen mode Exit fullscreen mode

Définit la réponse simulée : statut HTTP 200 et corps JSON.

Quand getUser(42) s’exécute, aucun appel réel n’est envoyé à api.example.com. nock renvoie directement la réponse configurée.

Tester les erreurs HTTP

Les tests utiles ne couvrent pas seulement les réponses 200. Vous devez aussi vérifier les erreurs, timeouts et réponses inattendues.

Exemple avec une erreur 500 :

test('throws when the API returns 500', async () => {
  nock('https://api.example.com')
    .get('/users/99')
    .reply(500);

  await expect(getUser(99)).rejects.toThrow('Request failed: 500');
});
Enter fullscreen mode Exit fullscreen mode

C’est l’un des principaux intérêts de nock : vous pouvez déclencher un 500 à la demande, sans dépendre d’une API réelle.

Si votre objectif est de tester plus finement les erreurs serveur, ce guide explique comment simuler une réponse d’erreur interne du serveur 500.

Vérifier que toutes les requêtes prévues ont été appelées

Une bonne pratique consiste à vérifier que vos mocks ont bien été consommés.

Utilisez scope.done() :

test('calls the expected endpoint', async () => {
  const scope = nock('https://api.example.com')
    .get('/users/42')
    .reply(200, { id: 42, name: 'Ada Lovelace' });

  await getUser(42);

  scope.done();
});
Enter fullscreen mode Exit fullscreen mode

Si getUser(42) n’appelle jamais /users/42, le test échoue.

Vous pouvez aussi vérifier globalement l’état de nock :

expect(nock.isDone()).toBe(true);
Enter fullscreen mode Exit fullscreen mode

Nettoyer les mocks entre les tests

Les intercepteurs nock peuvent polluer d’autres tests si vous ne les nettoyez pas.

Ajoutez un afterEach :

import nock from 'nock';

afterEach(() => {
  nock.cleanAll();
});
Enter fullscreen mode Exit fullscreen mode

Pour bloquer les appels réseau non mockés pendant les tests :

beforeAll(() => {
  nock.disableNetConnect();
});

afterAll(() => {
  nock.enableNetConnect();
});
Enter fullscreen mode Exit fullscreen mode

Si un test tente de contacter une vraie API sans mock correspondant, il échouera. C’est utile pour éviter les appels externes accidentels dans une suite CI.

Fonctionnalités nock utiles au quotidien

Réutiliser un intercepteur avec .persist()

Par défaut, un intercepteur nock est utilisé une seule fois.

nock('https://api.example.com')
  .get('/health')
  .reply(200, { status: 'ok' });
Enter fullscreen mode Exit fullscreen mode

Si votre code appelle plusieurs fois le même endpoint, utilisez .persist() :

nock('https://api.example.com')
  .persist()
  .get('/health')
  .reply(200, { status: 'ok' });
Enter fullscreen mode Exit fullscreen mode

Limiter le nombre d’appels avec .times(n)

Pour autoriser exactement trois appels :

nock('https://api.example.com')
  .get('/users/42')
  .times(3)
  .reply(200, { id: 42 });
Enter fullscreen mode Exit fullscreen mode

Simuler une réponse lente avec .delay(ms)

Pour tester la gestion des timeouts :

nock('https://api.example.com')
  .get('/slow-endpoint')
  .delay(2000)
  .reply(200, { ok: true });
Enter fullscreen mode Exit fullscreen mode

Matcher des chemins dynamiques

Vous pouvez utiliser une expression régulière :

nock('https://api.example.com')
  .get(/\/users\/\d+/)
  .reply(200, { ok: true });
Enter fullscreen mode Exit fullscreen mode

Utile lorsque les IDs ou paramètres changent selon les tests.

Matcher des query params

nock('https://api.example.com')
  .get('/users')
  .query({ page: 1, limit: 10 })
  .reply(200, [{ id: 1 }, { id: 2 }]);
Enter fullscreen mode Exit fullscreen mode

Pour accepter n’importe quelle query string :

nock('https://api.example.com')
  .get('/users')
  .query(true)
  .reply(200, []);
Enter fullscreen mode Exit fullscreen mode

Quand nock n’est plus le bon outil

nock est excellent pour un cas précis : intercepter le HTTP dans un seul processus Node.js pendant des tests automatisés.

Il devient moins adapté dès que la maquette doit être accessible en dehors de ce processus.

Exemples :

  • un développeur front-end veut pointer son navigateur vers une fausse API ;
  • une équipe mobile veut tester depuis un simulateur ;
  • une équipe QA veut explorer des cas limites manuellement ;
  • plusieurs dépôts doivent utiliser les mêmes réponses simulées ;
  • une démo produit nécessite une API stable sans backend réel.

Dans ces cas, il vous faut un serveur de maquette : une URL réelle qui répond à n’importe quel client HTTP.

Pour comparer les approches, consultez ces guides sur serveur de maquette vs serveur réel et la simulation d’API.

nock vs serveur de maquette hébergé avec Apidog

Pensez à nock et à un serveur de maquette hébergé comme deux couches complémentaires.

  • nock : idéal pour les tests unitaires Node.js.
  • Apidog : utile quand vous avez besoin d’un serveur de maquette partagé, accessible via une URL réelle.

Apidog permet de générer un serveur de maquette à partir de la conception de votre API. Vous définissez vos endpoints et vos schémas, puis l’équipe peut appeler une URL de mock commune.

Comparaison nock et serveur de maquette Apidog

Critère nock Serveur de maquette Apidog
Où il s’exécute Dans votre processus de test Node Serveur hébergé avec une URL réelle
Idéal pour Tests unitaires, simulation d’erreurs Intégration, tests manuels, travail inter-équipes
Qui peut l’atteindre Code dans le même processus N’importe quel client avec l’URL
Configuration Code dans chaque fichier de test Généré à partir de votre schéma d’API
Langages Node.js uniquement N’importe quel client, n’importe quel langage
Données réalistes Vous écrivez chaque réponse Maquette intelligente à partir du schéma et des noms de champs
Partage Non partageable Partagé au sein de toute l’équipe

Apidog ne remplace pas nock dans vos tests Jest ou Mocha. Si vous devez intercepter un fetch dans un test unitaire et vérifier le résultat, utilisez nock.

Utilisez plutôt un serveur de maquette lorsque le front-end, la QA, une équipe mobile ou un outil externe doit appeler la même fausse API.

Pour un exemple côté serveur, consultez ce guide pratique sur la simulation d’une API pour les tests. Vous pouvez aussi télécharger Apidog et créer une maquette à partir d’un fichier OpenAPI existant.

Alternatives à nock

nock n’est pas la seule option. Le bon choix dépend de l’endroit où votre code s’exécute.

MSW

MSW, pour Mock Service Worker, intercepte les requêtes côté navigateur via un service worker et côté Node via un intercepteur dédié.

C’est une bonne option si vous voulez partager des mocks entre le front-end et certains tests Node.js.

Documentation : MSW

Mocks manuels Jest

Vous pouvez mocker directement un module comme axios.

jest.mock('axios');
Enter fullscreen mode Exit fullscreen mode

C’est simple pour des cas courts, mais vous mockez le client HTTP, pas la couche HTTP elle-même. Le test devient donc lié à l’implémentation.

Ce tutoriel de simulation Jest couvre ce modèle.

Doubles de test avec Sinon ou le test runner Node.js

Vous pouvez aussi remplacer la fonction qui effectue l’appel HTTP par un stub.

C’est utile pour tester une logique métier isolée, mais vous perdez la vérification du chemin, de la méthode HTTP et des headers au niveau réseau.

Questions fréquentes

nock est-il gratuit ?

Oui. nock est open source sous licence MIT et s’installe gratuitement depuis npm.

npm install --save-dev nock
Enter fullscreen mode Exit fullscreen mode

nock fonctionne-t-il avec fetch et axios ?

Oui. nock intercepte au niveau des modules http et https de Node.js. Il fonctionne donc avec fetch, axios, got, node-fetch et les clients basés sur ces modules.

Puis-je utiliser nock dans le navigateur ?

Non. nock fonctionne uniquement avec Node.js, car il patch les modules HTTP natifs de Node.

Pour le navigateur, utilisez MSW ou un serveur de maquette hébergé. Cet aperçu des API de simulation en JavaScript présente les options possibles.

Quelle est la différence entre nock et un serveur de maquette ?

nock intercepte les requêtes dans votre processus de test. Il n’expose aucune URL réelle.

Un serveur de maquette écoute sur une URL que n’importe quel client peut appeler.

Utilisez :

  • nock pour les tests unitaires Node.js ;
  • un serveur de maquette pour le front-end, la QA, les tests manuels et le travail inter-équipes.

En résumé

nock est un choix solide pour simuler des appels HTTP dans les tests unitaires Node.js. Il rend vos tests plus rapides, plus déterministes, et vous permet de couvrir facilement les erreurs HTTP.

Utilisez-le lorsque la maquette reste dans un test automatisé.

Quand la maquette doit être partagée avec un navigateur, une application mobile, une équipe QA ou un autre dépôt, utilisez plutôt un serveur de maquette. Apidog peut générer ce serveur à partir de votre schéma d’API et fournir une URL commune à toute l’équipe. Téléchargez Apidog pour transformer une spécification OpenAPI en maquette fonctionnelle.

Top comments (0)