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.
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
ou avec pnpm :
pnpm add -D nock
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();
}
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' });
});
Ce test se lit ainsi :
nock('https://api.example.com')
Définit l’hôte à intercepter.
.get('/users/42')
Indique la méthode HTTP et le chemin attendus.
.reply(200, { id: 42, name: 'Ada Lovelace' })
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');
});
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();
});
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);
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();
});
Pour bloquer les appels réseau non mockés pendant les tests :
beforeAll(() => {
nock.disableNetConnect();
});
afterAll(() => {
nock.enableNetConnect();
});
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' });
Si votre code appelle plusieurs fois le même endpoint, utilisez .persist() :
nock('https://api.example.com')
.persist()
.get('/health')
.reply(200, { status: 'ok' });
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 });
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 });
Matcher des chemins dynamiques
Vous pouvez utiliser une expression régulière :
nock('https://api.example.com')
.get(/\/users\/\d+/)
.reply(200, { ok: true });
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 }]);
Pour accepter n’importe quelle query string :
nock('https://api.example.com')
.get('/users')
.query(true)
.reply(200, []);
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.
| 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');
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
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)