HTTP server mocking and expectations library for Node.js testing environments
67
This document covers nock's global state management functions for controlling activation, cleanup, network access, and monitoring interceptors across all scopes.
Manage nock's global activation state to control when HTTP interception is active.
function activate(): void;
function isActive(): boolean;const nock = require("nock");
// Activate nock globally
nock.activate();
// Check if nock is active
console.log(nock.isActive()); // true
// Create interceptors - these will now work
const scope = nock("https://api.example.com")
.get("/users")
.reply(200, []);Note: Nock is automatically activated when you import/require it, so manual activation is typically not needed unless you've previously disabled it.
Remove all interceptors and clean up nock's state.
function cleanAll(): void;// Create multiple scopes with interceptors
nock("https://api.example.com").get("/users").reply(200, []);
nock("https://api.example.com").post("/users").reply(201, {});
nock("https://other-api.com").get("/data").reply(200, {});
console.log(nock.activeMocks().length); // 3
// Clean up all interceptors
nock.cleanAll();
console.log(nock.activeMocks().length); // 0This is commonly used in test cleanup:
// Jest/Mocha example
afterEach(() => {
nock.cleanAll();
});Get information about active and pending interceptors across all scopes.
function pendingMocks(): string[];
function activeMocks(): string[];
function isDone(): boolean;Get descriptions of interceptors that have been defined but not yet matched:
nock("https://api.example.com")
.get("/users")
.reply(200, [])
.post("/users")
.reply(201, {});
console.log(nock.pendingMocks());
// Output: [
// "GET https://api.example.com:443/users",
// "POST https://api.example.com:443/users"
// ]
// After making a GET request to /users
console.log(nock.pendingMocks());
// Output: ["POST https://api.example.com:443/users"]Get descriptions of all currently active interceptors (both matched and unmatched):
const scope1 = nock("https://api.example.com")
.get("/users")
.reply(200, []);
const scope2 = nock("https://other-api.com")
.get("/data")
.reply(200, {});
console.log(nock.activeMocks());
// Output: [
// "GET https://api.example.com:443/users",
// "GET https://other-api.com:443/data"
// ]Check if all interceptors across all scopes have been satisfied:
nock("https://api.example.com")
.get("/users")
.reply(200, [])
.post("/users")
.reply(201, {});
console.log(nock.isDone()); // false
// Make both requests...
// After both requests are made:
console.log(nock.isDone()); // trueControl whether real HTTP requests are allowed when no interceptors match.
function disableNetConnect(): void;Prevent any real HTTP requests from being made:
nock.disableNetConnect();
// This will throw NetConnectNotAllowedError if no interceptor matches
// http.get("https://real-api.com/data", callback);This is the default behavior and is useful for ensuring tests don't make unexpected network calls.
function enableNetConnect(
matcher?: string | RegExp | ((host: string) => boolean)
): void;Allow real HTTP requests, optionally with restrictions:
// Allow all real HTTP requests
nock.enableNetConnect();
// Allow requests to specific host
nock.enableNetConnect("localhost");
// Allow requests matching regex pattern
nock.enableNetConnect(/^localhost/);
// Allow requests based on function predicate
nock.enableNetConnect((host) => {
return host.includes("localhost") || host.includes("127.0.0.1");
});// Allow localhost for integration tests
nock.enableNetConnect("localhost");
// Allow test database connections
nock.enableNetConnect((host) => host.includes("testdb"));
// Re-disable after tests
afterEach(() => {
nock.disableNetConnect();
});Remove specific interceptors and abort pending requests.
function removeInterceptor(interceptor: Interceptor | ReqOptions): boolean;Remove a specific interceptor from nock's registry:
const scope = nock("https://api.example.com");
const interceptor = scope.get("/users").reply(200, []);
// Remove this specific interceptor
const removed = nock.removeInterceptor(interceptor);
console.log(removed); // true if successfully removed
// Can also remove by request options
nock.removeInterceptor({
hostname: "api.example.com",
port: 443,
method: "GET",
path: "/users"
});function abortPendingRequests(): void;Abort all pending HTTP requests that are waiting for responses:
// If you have pending requests that are stuck or taking too long
nock.abortPendingRequests();This is useful in test teardown to ensure no hanging requests:
afterEach(() => {
nock.abortPendingRequests();
nock.cleanAll();
});Monitor nock's behavior using the global event emitter.
const emitter: NodeJS.EventEmitter;Listen for requests that don't match any interceptor:
nock.emitter.on("no match", (req) => {
console.log("Unmatched request:", req.method, req.path);
console.log("Headers:", req.headers);
});
// Enable net connect to allow unmatched requests
nock.enableNetConnect();
// This request won't match any interceptor and will trigger the event
// (then proceed to the real server because net connect is enabled)// Track when interceptors are used
nock.emitter.on("no match", (req) => {
// Log unmatched requests for debugging
console.warn(`Unmatched request: ${req.method} ${req.path}`);
// Optionally fail tests on unmatched requests
if (process.env.NODE_ENV === "test") {
throw new Error(`Unexpected HTTP request: ${req.method} ${req.path}`);
}
});Understand the errors that nock's global functions can throw.
Thrown when disableNetConnect() is active and a request doesn't match any interceptor:
nock.disableNetConnect();
try {
// This will throw if no interceptor matches
await fetch("https://unmocked-api.com/data");
} catch (error) {
if (error.code === "ENETUNREACH") {
console.log("Real network request was blocked by nock");
}
}Here's how to set up nock for a complete test suite:
const nock = require("nock");
describe("API Integration Tests", () => {
beforeEach(() => {
// Ensure nock is active and net connect is disabled
nock.activate();
nock.disableNetConnect();
// Allow localhost for test database/server
nock.enableNetConnect("localhost");
});
afterEach(() => {
// Verify all interceptors were used
if (!nock.isDone()) {
console.warn("Unused interceptors:", nock.pendingMocks());
}
// Clean up all interceptors
nock.abortPendingRequests();
nock.cleanAll();
});
it("should handle user creation", async () => {
const scope = nock("https://api.example.com")
.post("/users", { name: "Alice" })
.reply(201, { id: 1, name: "Alice" });
// Your test code here...
// Verify the interceptor was used
expect(scope.isDone()).toBe(true);
});
it("should handle network errors gracefully", async () => {
nock("https://api.example.com")
.get("/users")
.replyWithError("Network timeout");
// Test your error handling...
});
});Load and define interceptors from JSON fixture files programmatically.
function loadDefs(path: string): Definition[];Load fixture definitions from a JSON file without creating interceptors:
const nock = require("nock");
// Load definitions from file
const definitions = nock.loadDefs("./fixtures/api-responses.json");
console.log(`Loaded ${definitions.length} fixture definitions`);
// Process definitions before creating interceptors
const processedDefs = definitions.map(def => {
// Modify definitions as needed
if (def.scope.includes("api.example.com")) {
def.response = { modified: true, ...JSON.parse(def.response) };
}
return def;
});
// Create interceptors from processed definitions
const scopes = nock.define(processedDefs);Note: This function requires the fs module and will throw an error in browser environments.
function load(path: string): Scope[];Load fixture definitions from a JSON file and immediately create interceptors:
// Load fixtures and create interceptors in one step
const scopes = nock.load("./fixtures/user-api.json");
console.log(`Created ${scopes.length} scopes from fixtures`);
// Equivalent to: nock.define(nock.loadDefs(path))function define(definitions: Definition[]): Scope[];Create interceptors from an array of definition objects:
const definitions = [
{
scope: "https://api.example.com:443",
method: "GET",
path: "/users",
status: 200,
response: [{ id: 1, name: "Alice" }]
},
{
scope: "https://api.example.com:443",
method: "POST",
path: "/users",
body: { name: "Bob" },
status: 201,
response: { id: 2, name: "Bob" }
}
];
// Create interceptors from definitions
const scopes = nock.define(definitions);
console.log(`Created ${scopes.length} scopes`);
// Each scope can be used normally
scopes.forEach(scope => {
console.log("Active mocks:", scope.activeMocks());
});Fixture files should contain an array of Definition objects:
[
{
"scope": "https://api.example.com:443",
"method": "GET",
"path": "/users",
"status": 200,
"response": "[{\"id\":1,\"name\":\"Alice\"}]",
"headers": {
"content-type": "application/json"
}
},
{
"scope": "https://api.example.com:443",
"method": "POST",
"path": "/users",
"body": "{\"name\":\"Bob\"}",
"status": 201,
"response": "{\"id\":2,\"name\":\"Bob\"}",
"reqheaders": {
"content-type": "application/json"
}
}
]// Load and process fixtures with scope filtering
const rawDefs = nock.loadDefs("./fixtures/comprehensive-api.json");
// Filter definitions by scope
const apiDefs = rawDefs.filter(def =>
def.scope.includes("api.example.com")
);
// Add scope-level filtering before defining
const scope = nock("https://api.example.com", {
filteringScope: (scope) => scope.replace(/\d+/, "ID")
});
// Define interceptors with preprocessing
const scopes = nock.define(apiDefs.map(def => ({
...def,
// Add default options to all definitions
options: {
...def.options,
allowUnmocked: true
}
})));Use global functions for debugging interceptor issues:
// Log all active interceptors
console.log("Active mocks:", nock.activeMocks());
// Log pending interceptors
console.log("Pending mocks:", nock.pendingMocks());
// Check global state
console.log("Nock is active:", nock.isActive());
console.log("All interceptors done:", nock.isDone());
// Set up detailed logging
nock.emitter.on("no match", (req) => {
console.log("❌ No match for:", req.method, req.path);
console.log("Available interceptors:", nock.activeMocks());
});Install with Tessl CLI
npx tessl i tessl/npm-nockdocs
evals
scenario-1
scenario-2
scenario-3
scenario-4
scenario-5
scenario-6
scenario-7
scenario-8
scenario-9
scenario-10