Nock HTTP Mocking for Node.js
Nock is a robust HTTP server mocking and expectations library designed specifically for Node.js environments. It enables developers to test modules that make outbound HTTP/HTTPS requests in isolation by intercepting network traffic and responding with predefined data. The current stable release series is v14, with v14.0.12 being the latest as of April 2026. An actively developed v15 beta series introduces new features such as `passthrough()` for granular control over unmocked requests and improved error handling, but is not yet recommended for production use due to an accidental v15.0.0 release that was later deprecated. Nock maintains an active release cadence, frequently publishing bug fixes and beta updates. Its key differentiators include comprehensive control over request matching (by host, path, query, body, headers, and HTTP verb), the ability to define repeatable or one-time responses, and functionalities for recording and playing back HTTP interactions using 'nock-back' for fixture-based testing. It aims to provide deep control over the network layer to facilitate reliable unit and integration testing without relying on actual network connectivity.
Common errors
-
Nock: No match for request
cause The actual outgoing HTTP request did not precisely match any defined Nock interceptor's criteria (URL, path, method, headers, query, or body).fixCarefully review the `nock` definition and the actual outgoing request. Use `nock.pendingMocks()` to identify unmatched scopes or `nock.on('request')` and `nock.recorder.rec()` for debugging mismatch details. Ensure all parameters (host, path, method, query, body, headers) align exactly. -
TypeError: nock is not a function
cause This typically occurs in CommonJS environments if `require('nock').default` is used instead of `require('nock')`, or if `nock` is mistakenly treated as a named import in some ESM setups.fixFor CommonJS, use `const nock = require('nock');`. For ESM, ensure `import nock from 'nock';` is used, as `nock` is the default export. Methods like `cleanAll()` are accessed via `nock.cleanAll()`. -
Error: Aborted
-
ETIMEDOUT
cause A mocked request either timed out waiting for a Nock response, or the Nock interceptor itself has a `delayConnection()` or `delay()` option set that is longer than the client's timeout, or fake timers are not advanced.fixVerify that `nock` mocks are responding within expected timeframes. If using `delay()` or `delayConnection()`, adjust them or ensure your test runner's fake timers (e.g., `jest.runAllTimers()`) are correctly advancing. -
Error: Request failed with status code 404 (or other non-mocked status)
cause This usually indicates that `nock` was not active, the specific mock was already consumed (not persistent), or the request was not intercepted by Nock at all, leading to a real network request (which then failed).fixEnsure `nock.activate()` has been called. If the mock should apply to multiple requests, add `.persist()` to the interceptor definition. Check `nock.isDone()` before assertions to confirm all mocks were consumed, or `nock.pendingMocks()` for unfulfilled expectations. Reconfirm the URL/path of the request and mock.
Warnings
- breaking Nock v15.0.0 was released by accident and contains known issues. It has been immediately deprecated. Users should avoid installing v15.0.0 directly and instead continue using the latest v14 stable releases (e.g., v14.0.12) or explicitly use the v15 beta series (e.g., v15.0.0-beta.10) for pre-release features.
- breaking Nock now strictly enforces Node.js engine compatibility. Versions older than Node.js 18.20.0 or specific patches within Node.js 20 may not be supported, potentially leading to runtime errors or unexpected behavior.
- breaking When using `replyWithError()`, Nock v14.0.10 and later expect an actual `Error` object as the argument, not a plain JavaScript object. Providing a plain object will no longer be treated as an error and may lead to unexpected behavior.
- gotcha Nock interceptors are active immediately upon creation. To prevent unintended side effects or test pollution, always call `nock.cleanAll()` in your test teardown hooks (e.g., `afterEach`, `afterAll`) to remove all pending and active mocks.
- gotcha By default, Nock intercepts all HTTP/HTTPS requests once activated. If you need to allow specific 'real' network requests (e.g., to a local API or specific external services) while mocking others, you must explicitly configure `nock.enableNetConnect()`.
Install
-
npm install nock -
yarn add nock -
pnpm add nock
Imports
- nock
const nock = require('nock').default;import nock from 'nock';
- Scope
import { Scope } from 'nock';import type { Scope } from 'nock'; - nock.cleanAll
import { cleanAll } from 'nock'; cleanAll();nock.cleanAll();
Quickstart
import nock from 'nock';
import { strict as assert } from 'node:assert';
// Define the base URL for the API to mock
const API_BASE_URL = 'http://api.example.com';
const FAKE_API_PATH = '/users/123';
async function getUserData(userId: string) {
const response = await fetch(`${API_BASE_URL}/users/${userId}`, {
headers: { 'Accept': 'application/json' }
});
if (!response.ok) {
throw new Error(`HTTP error! Status: ${response.status}`);
}
return response.json();
}
async function runTest() {
// 1. Set up the Nock interceptor for a GET request
const scope = nock(API_BASE_URL)
.matchHeader('Accept', 'application/json')
.get(FAKE_API_PATH)
.reply(200, { id: '123', name: 'Nock User', email: 'user@example.com' }, {
'Content-Type': 'application/json',
'X-Nock-Mocked': 'true',
'Cache-Control': 'no-cache'
});
try {
// 2. Make the HTTP request that Nock will intercept
console.log('Fetching user data...');
const userData = await getUserData('123');
// 3. Assert the response data matches the mock
assert.deepStrictEqual(userData, {
id: '123',
name: 'Nock User',
email: 'user@example.com'
}, 'User data should match mock payload.');
console.log('Successfully received mocked user data.');
// 4. Assert that all Nock expectations were met for this scope
assert(scope.isDone(), 'Nock scope should be done, all expectations met.');
console.log('Nock expectations met for the defined scope.');
} catch (error) {
console.error('Test failed:', error);
process.exit(1);
} finally {
// 5. Clean up Nock mocks to prevent interference with other tests
nock.cleanAll();
console.log('Nock mocks cleaned up.');
}
}
// Ensure Nock is active; often implicit after import, but good for clarity
nock.activate();
runTest();