Profiles·Public

nock

semver>=9.0.0postconditions17functions11last verified2026-06-24coverage score91%

Postconditions: what we check

  • nock · unmatched-request-throws
    error
    WhenAn HTTP request is made that does not match any defined interceptor and nock.disableNetConnect() has been called
    ThrowsNetConnectNotAllowedError (error.code === 'ENETUNREACH')
    Required handlingTest assertions MUST account for this error. The most common cause is a URL path, method, query parameter, header, or body mismatch between the real request and the mock definition. Fix the mock to match the actual request, or allow the specific host with nock.enableNetConnect(host).
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[1][2]
  • disableNetConnect · real-requests-blocked
    info
    Whencalled without arguments
    Returnsundefined; all subsequent unmatched HTTP requests will throw
    Required handlingNo action required — use the returned value as needed.
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[1]
  • cleanAll · all-interceptors-removed
    info
    Whencalled at any point
    Returnsundefined; all pending interceptors are cleared
    Required handlingNo action required — use the returned value as needed.
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[3]
  • restore · interception-deactivated
    info
    Whencalled after interception is no longer needed
    Returnsundefined; http module is restored to its original state
    Required handlingNo action required — use the returned value as needed.
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[4]
  • isDone · returns-false-for-unused-mocks
    warning
    Whenone or more interceptors on the scope have not been matched by any request
    Returnsfalse
    Required handlingTests SHOULD assert scope.isDone() after the code under test runs. A false return indicates the code did not make the expected request, the mock URL/method/body does not match the real request, or there is a bug in the test logic.
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[5][6]
  • isDone · returns-true-when-all-consumed
    info
    Whenall interceptors on the scope have been matched at least once
    Returnstrue
    Required handlingNo action required — use the returned value as needed.
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[5]
  • load · load-file-not-found
    error
    WhenThe path argument does not point to an existing file, or the process lacks read permission for the file
    ThrowsError with code ENOENT from fs.readFileSync — "no such file or directory, open '<path>'"
    Required handlingWrap nock.load() in a try-catch. A missing fixture file means all interceptors are absent and all HTTP calls in the test will fail or hit the real network. Test setup MUST validate the fixture path exists before calling load().
    costlowin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[7][8]
  • load · load-invalid-json
    error
    WhenThe fixture file exists but contains invalid JSON (e.g. truncated recording, manual edit error, encoding issue)
    ThrowsSyntaxError from JSON.parse — "Unexpected token ... in JSON at position N"
    Required handlingValidate fixture files are well-formed JSON before committing them. A SyntaxError from nock.load() crashes the entire test suite setup (beforeAll/beforeEach fails), causing all tests in the suite to error rather than fail, making the root cause harder to diagnose.
    costlowin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[7]
  • loadDefs · loaddefs-file-not-found
    error
    WhenThe path argument does not point to an existing file
    ThrowsError with code ENOENT from fs.readFileSync
    Required handlingSame as nock.load() — wrap in try-catch. Missing fixture means all definitions are absent. Callers that transform definitions before passing to nock.define() must guard against this error in the transformation pipeline.
    costlowin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[7]
  • Scope.done · scope-done-unused-mocks-throw
    error
    WhenOne or more interceptors on the scope have not been matched by a real HTTP request when scope.done() is called
    ThrowsAssertionError: "Mocks not yet satisfied:\n<method> <url>" — lists each pending mock
    Required handlingCall scope.done() only after the code under test has had the opportunity to make all expected HTTP calls. If done() throws, the test has a logic error: either the code under test did not make the expected request, or the mock URL/method/body does not match the actual request. Do not suppress the AssertionError — it is an intentional test signal.
    costlowin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[5]
  • Scope.done · scope-done-swallowed-in-async-callback
    warning
    Whenscope.done() is called inside an async callback (setTimeout, promise .then, or event handler) without the test framework being aware of the async assertion
    Required handlingAlways call scope.done() synchronously at the end of the test body, or ensure the test framework is awaiting async assertions (use expect.assertions(n) in Jest, or return the promise from the test function).
    costlowin prodimmediate exceptionusers seeservice unavailablevisibilitysilent
    Sources[5]
  • back · back-fixtures-not-set
    error
    Whennock.back.fixtures has not been set to a directory path before calling nock.back()
    ThrowsError: "Back requires nock.back.fixtures to be set\n\tnock.back.fixtures = '/path/to/fixtures/'"
    Required handlingSet nock.back.fixtures = path.join(__dirname, 'fixtures') in a top-level beforeAll hook before any test that uses nock.back(). Missing this causes an immediate throw (not a rejected Promise) — the error surfaces synchronously during the call.
    costlowin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[9]
  • back · back-unknown-mode
    error
    Whennock.back.setMode() is called with a string that is not one of 'wild', 'dryrun', 'record', 'update', or 'lockdown'
    ThrowsError — "Unknown mode: <value>"
    Required handlingUse only the five documented BackMode values. The mode is typically set from an environment variable (process.env.NOCK_BACK_MODE). Validate the env var value against the allowed set before passing to setMode().
    costlowin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[9]
  • define · define-method-required
    error
    WhenAny Definition in the passed array is missing a `method` property
    ThrowsError — "Method is required"
    Required handlingValidate every Definition has a `method` field before calling define(). Typical cause: a fixture transform pipeline that strips or renames the method field, or a hand-written fixture missing the field. The throw happens at index N when the Nth def has no method, so any defs preceding it have already been registered as interceptors — partial setup state is left behind. Always wrap the define() call in try/catch and call nock.cleanAll() in the catch to reset state.
    costlowin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[7]
  • define · define-reply-not-numeric
    error
    WhenA Definition has a `reply` property that is not parseable as an integer (NaN after parseInt) — typically a string like "OK" or "200 OK"
    ThrowsError — "`reply`, when present, must be a numeric string"
    Required handlingThe `reply` field accepts only numeric strings ("200", "404", etc.) for backward-compatibility with old nock fixtures. Use the `status` field for new fixtures (it accepts a number directly). When loading legacy fixtures from external sources, sanitize the reply field — strip non-numeric content or migrate to status. Failure mode: test suite crashes on beforeAll, blocking all tests in the file.
    costlowin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[7]
  • define · define-mismatched-port
    error
    WhenA Definition has both `scope` (with a port in the URL) and a `port` property, and the two ports do not match
    ThrowsError — "Mismatched port numbers in scope and port properties of nock definition."
    Required handlingWhen transforming fixture definitions (e.g. rewriting hostnames or ports for a test environment), update BOTH the scope URL and the port property together — they must agree. Common cause: a transform that rewrites the scope URL but forgets to also update the legacy port field. The throw aborts the entire define() call, leaving partial interceptor state.
    costlowin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[7]
  • recorder.rec · rec-already-in-progress
    error
    Whennock.recorder.rec() is called while a previous recording session is still active (nock.recorder.clear() and nock.restore() have not been invoked)
    ThrowsError — "Nock recording already in progress"
    Required handlingCall nock.restore() and nock.recorder.clear() before re-entering record mode. Typical cause: test setup spawns multiple record blocks across beforeEach hooks without intervening teardown, or a recording was started in module-level code and a test also tries to start one. Failure mode: synchronous throw aborts the calling code path — if invoked from a beforeAll/beforeEach hook the entire suite errors out. Pair every recorder.rec() with a matching nock.restore() + recorder.clear() in afterAll/afterEach.
    costlowin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[10][11]

Sources

Every postcondition cites at least one of these. Grouped by source type; numbered to match the footnotes above.

Official documentation
  • [6]
    snyk.io/advisor/npm-package/nock
    Nock.IsDone
  • [8]
    nodejs.org/api/fs.html
    Fs
Source code
Issues & pull requests

Research notes

Curator notes from SOURCES.md captured when the profile was written so you can verify the reasoning, not just the rules.

Nark profile Sources: nock

Package: nock Version Range: >=9.0.0 Type: Testing Utility - HTTP Request Mocking and Interception Last Updated: 2026-02-27


Overview

nock is a widely-used HTTP request mocking library for Node.js testing. It intercepts outgoing HTTP/HTTPS requests and allows developers to define expected requests and responses without making actual network calls. This Nark profile focuses on throw-based error patterns that occur when mocks are misconfigured, requests don't match expectations, or proper cleanup is not performed.

Primary Repository: https://github.com/nock/nock NPM Package: https://www.npmjs.com/package/nock Documentation: https://github.com/nock/nock#readme


Error Categories

1. Unmatched Request Errors (NetConnectNotAllowedError)

When nock.disableNetConnect() is enabled (recommended best practice), any HTTP request that doesn't match a defined mock will throw a NetConnectNotAllowedError. This is the most common error pattern in nock usage.

Error Details:

  • Error Name: NetConnectNotAllowedError
  • Error Code: ENETUNREACH
  • Message Format: "Nock: Disallowed net connect for [hostname:port]"
  • Severity: HIGH (breaks tests immediately)

Source: nock GitHub Issues #884

Example Error:

nock.disableNetConnect();
const req = http.get('http://google.com/');
req.on('error', err => {
  console.log(err);
  // NetConnectNotAllowedError: Nock: Disallowed net connect for "google.com:80"
});

Source: nock documentation on disableNetConnect

Common Causes:

  1. URL mismatch - Mock defines /users but code requests /users/123
  2. Method mismatch - Mock defines GET but code makes POST request
  3. Query parameter mismatch - Mock missing query params that code includes
  4. Header mismatch - Mock expects specific headers that aren't sent
  5. Body mismatch - POST/PUT body doesn't match expected format
  6. Hostname mismatch - Mock defines api.example.com but code requests www.example.com

Real-World Impact:

  • 40-50% of nock-related test failures are due to unmatched requests
  • Often indicates incorrect test setup or API changes
  • Can mask real bugs if not properly handled

Detection Strategy:

// ❌ BAD - Unmatched request causes test failure
nock('https://api.example.com')
  .get('/users')
  .reply(200, { users: [] });

// This will throw NetConnectNotAllowedError
await fetch('https://api.example.com/users/123');

Source: Testing Node.js SDKs with nock


2. Scope Lifecycle Errors

nock uses scopes to manage mock definitions. Each scope tracks whether its expected requests have been made. Improper scope management leads to test pollution and false positives/negatives.

2.1 Scope Not Done (Unused Mocks)

When a mock is defined but never called, the scope remains "not done". This indicates either:

  • The code under test didn't make the expected request
  • The mock configuration is incorrect
  • The test logic has a bug

Detection Method: scope.isDone() returns false

Example:

const scope = nock('https://api.example.com')
  .get('/users')
  .reply(200, []);

// Test runs but never calls the API
// scope.isDone() === false

// Best practice: Check in afterEach
afterEach(() => {
  if (!nock.isDone()) {
    console.error('Pending mocks:', nock.pendingMocks());
    throw new Error('Not all nock interceptors were used');
  }
});

Source: Ensure All Nock Interceptors Are Used

Source: michaelheap.com - Ensure all nock mock interceptors are used

2.2 Scope Leaks (Cross-Test Pollution)

Without proper cleanup, mocks can persist between tests, causing:

  • False positives (test passes using previous test's mocks)
  • False negatives (test fails due to unexpected mocks)
  • Flaky tests (order-dependent failures)

Common Patterns:

Pattern 1: Missing nock.cleanAll() in afterEach

// ❌ BAD - No cleanup
test('test 1', async () => {
  nock('https://api.example.com').get('/data').reply(200, { data: 'test1' });
  // Test runs...
  // Mock persists after test completes
});

test('test 2', async () => {
  // This test might accidentally use test 1's mock!
});

// ✅ GOOD - Proper cleanup
afterEach(() => {
  nock.cleanAll();
});

Source: nock GitHub Issues #705 - Tests aren't cleaning up nock scope correctly

Pattern 2: persist() Without Cleanup

// ❌ BAD - persist() leaks to other tests
test('test 1', async () => {
  nock('https://api.example.com')
    .persist() // This mock will be used indefinitely!
    .get('/data')
    .reply(200, {});

  // Test runs...
});

// ✅ GOOD - Clean up persistent mocks
afterEach(() => {
  nock.cleanAll(); // Removes persistent mocks too
});

Source: nock official documentation

2.3 pendingMocks() for Debugging

The nock.pendingMocks() function returns an array of unused mock specifications, useful for debugging scope issues.

Example:

afterEach(() => {
  const pending = nock.pendingMocks();
  if (pending.length > 0) {
    console.error('Unused mocks:', pending);
    nock.cleanAll();
    throw new Error(`${pending.length} mocks were not used`);
  }
});

Source: Snyk Advisor - nock.pendingMocks


3. Configuration Errors

Incorrect mock configuration leads to runtime errors or unexpected behavior.

3.1 Invalid URL Patterns

Error: Malformed URLs or regex patterns cause parsing errors.

// ❌ BAD - Invalid regex
nock('https://api.example.com')
  .get(/\/users\/[invalid/) // Syntax error in regex
  .reply(200);

// ❌ BAD - Invalid URL format
nock('not-a-valid-url')
  .get('/data')
  .reply(200);

// ✅ GOOD - Valid patterns
nock('https://api.example.com')
  .get(/\/users\/\d+/) // Valid regex
  .reply(200);

3.2 Header Matching Errors

Headers are matched case-insensitively, but values must match exactly (unless using regex).

// ❌ BAD - Header value mismatch
nock('https://api.example.com')
  .get('/data')
  .reply(200, { headers: { 'authorization': 'Bearer token123' } });

// Code sends: { 'authorization': 'Bearer token456' }
// Result: NetConnectNotAllowedError

// ✅ GOOD - Flexible header matching
nock('https://api.example.com')
  .get('/data')
  .matchHeader('authorization', /^Bearer /)
  .reply(200);

Source: nock documentation on request matching

3.3 Body Matching Errors

POST/PUT/PATCH requests require body matching. Mismatched bodies cause unmatched request errors.

// ❌ BAD - Body mismatch
nock('https://api.example.com')
  .post('/users', { name: 'Alice' })
  .reply(201);

// Code sends: { name: 'Alice', email: 'alice@example.com' }
// Result: NetConnectNotAllowedError

// ✅ GOOD - Flexible body matching
nock('https://api.example.com')
  .post('/users', body => body.name === 'Alice')
  .reply(201);

4. Network Control Errors

4.1 disableNetConnect() Best Practice

Recommendation: Always call nock.disableNetConnect() in test setup to catch accidental real HTTP requests.

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

afterAll(() => {
  nock.enableNetConnect(); // Re-enable for cleanup
});

Source: nock documentation

4.2 Selective NetConnect Enabling

Allow specific hosts while blocking others:

// Allow localhost for testing local servers
nock.disableNetConnect();
nock.enableNetConnect('localhost');
nock.enableNetConnect('127.0.0.1');
nock.enableNetConnect(/^.*\.local$/); // Allow *.local domains

Source: nock documentation on enableNetConnect


5. Recording Errors

nock's recorder allows capturing real HTTP requests for playback in tests. Improper usage can lead to errors or security issues.

5.1 Missing nock.restore() After Recording

Error: Forgetting to call nock.restore() after recording leaves nock in interception mode.

// ❌ BAD - No restore
nock.recorder.rec({ output_objects: true });
// ... make requests ...
const recordings = nock.recorder.play();
// nock still intercepting requests!

// ✅ GOOD - Proper cleanup
nock.recorder.rec({ output_objects: true });
// ... make requests ...
const recordings = nock.recorder.play();
nock.restore(); // Stop recording

Source: nock documentation on recording

Source: CloudDefense - Top 10 Examples of nock code

5.2 Recording Sensitive Data

Security Risk: Recording real API requests can capture sensitive data (API keys, passwords, tokens).

Best Practice:

nock.recorder.rec({
  output_objects: true,
  dont_print: true, // Don't print to console
  enable_reqheaders_recording: false // Don't record sensitive headers
});

// ... make requests ...
const recordings = nock.recorder.play();

// Sanitize recordings before saving
const sanitized = recordings.map(r => ({
  ...r,
  headers: {}, // Remove sensitive headers
  rawHeaders: [] // Remove raw headers
}));

nock.restore();

Source: Why did Nock not record all the api requests?

5.3 output_objects vs Default Output

Recording modes:

  • Default: Generates JavaScript code as strings
  • output_objects: Returns structured objects for programmatic use
// Default mode (code generation)
nock.recorder.rec();
// ... make requests ...
nock.recorder.play(); // Returns array of code strings

// Object mode (structured data)
nock.recorder.rec({ output_objects: true });
// ... make requests ...
const objects = nock.recorder.play(); // Returns array of objects

Source: nock GitHub Issues #816 - Recording always includes rawHeaders


API Reference

Core Methods

nock(host)

Creates a scope for mocking requests to the specified host.

const scope = nock('https://api.example.com');

Returns: Scope object

Throws: Error if host is invalid


scope.get(path)

Defines a GET request mock.

scope.get('/users').reply(200, []);

Parameters:

  • path - String, RegExp, or function

Returns: Interceptor (chainable)


scope.post(path, body?)

Defines a POST request mock.

scope.post('/users', { name: 'Alice' }).reply(201);

Parameters:

  • path - String, RegExp, or function
  • body - Expected request body (optional)

Returns: Interceptor (chainable)


scope.isDone()

Checks if all mocks in this scope have been used.

const scope = nock('https://api.example.com').get('/data').reply(200);
// ... make request ...
console.log(scope.isDone()); // true if request was made

Returns: Boolean

Best Practice: Call in afterEach to verify all mocks were used.

Source: Snyk Advisor - nock.isDone


nock.cleanAll()

Removes all active interceptors.

afterEach(() => {
  nock.cleanAll();
});

Critical for: Preventing scope leaks between tests.

Source: Jack Franklin - Mocking API Requests in Node tests


nock.pendingMocks()

Returns array of unused mock specifications.

const pending = nock.pendingMocks();
if (pending.length > 0) {
  console.error('Unused mocks:', pending);
}

Returns: string[]

Use Case: Debugging scope issues


nock.disableNetConnect()

Blocks all HTTP requests except those matched by nock.

nock.disableNetConnect();

Throws: NetConnectNotAllowedError for unmatched requests

Best Practice: Call in beforeAll() or beforeEach()


nock.enableNetConnect(pattern?)

Re-enables HTTP requests (optionally for specific hosts).

nock.enableNetConnect(); // Enable all
nock.enableNetConnect('localhost'); // Enable localhost only
nock.enableNetConnect(/\.local$/); // Enable *.local domains

nock.restore()

Restores original http.request functionality after recording.

nock.recorder.rec();
// ... make requests ...
nock.recorder.play();
nock.restore(); // Stop intercepting

Critical after: Using nock.recorder


nock.recorder.rec(options)

Starts recording real HTTP requests.

Options:

{
  output_objects?: boolean;  // Return objects instead of code strings
  dont_print?: boolean;      // Don't print to console
  enable_reqheaders_recording?: boolean; // Record request headers
}

Example:

nock.recorder.rec({
  output_objects: true,
  dont_print: true
});

Source: nock documentation on recorder


nock.recorder.play()

Returns recorded requests.

const recordings = nock.recorder.play();
// Returns: string[] (default) or object[] (with output_objects: true)

interceptor.persist()

Makes the interceptor reusable (doesn't remove after first use).

nock('https://api.example.com')
  .persist()
  .get('/data')
  .reply(200, {});

// This mock can be used multiple times

Warning: Can cause scope leaks if not cleaned up with nock.cleanAll()


interceptor.reply(statusCode, body?, headers?)

Defines the response for a mocked request.

scope
  .get('/users')
  .reply(200, [{ id: 1, name: 'Alice' }], { 'x-custom': 'header' });

Parameters:

  • statusCode - HTTP status code
  • body - Response body (optional)
  • headers - Response headers (optional)

interceptor.matchHeader(name, value)

Requires specific request header to match.

scope
  .get('/data')
  .matchHeader('authorization', /^Bearer /)
  .reply(200);

Parameters:

  • name - Header name (case-insensitive)
  • value - String, RegExp, or function

Best Practices

1. Always Clean Up After Tests

afterEach(() => {
  nock.cleanAll();
});

Prevents: Scope leaks, flaky tests, false positives/negatives

Source: nock GitHub Issues #705


2. Verify All Mocks Are Used

afterEach(() => {
  if (!nock.isDone()) {
    const pending = nock.pendingMocks();
    console.error('Pending mocks:', pending);
    nock.cleanAll();
    throw new Error('Not all nock interceptors were used');
  }
  nock.cleanAll();
});

Catches: Incorrect mock setup, missing API calls, test logic bugs

Source: Ensure All Nock Interceptors Are Used


3. Disable Net Connect in Tests

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

afterAll(() => {
  nock.enableNetConnect();
});

Prevents: Accidental real HTTP requests, flaky tests, external dependencies

Source: Testing Node.js SDKs with nock


4. Check Scope Before Assertions

test('fetches user data', async () => {
  const scope = nock('https://api.example.com')
    .get('/users/123')
    .reply(200, { id: 123, name: 'Alice' });

  const result = await fetchUser(123);

  // Check scope FIRST (before assertions)
  expect(scope.isDone()).toBe(true);

  // Then check result
  expect(result.name).toBe('Alice');
});

Rationale: If assertion fails first, scope check never runs, hiding mock issues.

Source: Testing best practices


5. Use Flexible Matching for Dynamic Data

// ❌ BAD - Brittle exact match
nock('https://api.example.com')
  .post('/users', { name: 'Alice', timestamp: 1234567890 })
  .reply(201);

// ✅ GOOD - Flexible function matcher
nock('https://api.example.com')
  .post('/users', body => body.name === 'Alice')
  .reply(201);

Handles: Dynamic timestamps, UUIDs, generated IDs


6. Sanitize Recorded Data

nock.recorder.rec({ output_objects: true, dont_print: true });
// ... make requests ...
const recordings = nock.recorder.play();

// Remove sensitive data
const sanitized = recordings.map(recording => ({
  ...recording,
  scope: recording.scope,
  method: recording.method,
  path: recording.path,
  body: recording.body,
  status: recording.status,
  response: recording.response,
  // REMOVE sensitive fields
  headers: {},
  rawHeaders: [],
  reqheaders: {}
}));

nock.restore();

Prevents: Leaking API keys, tokens, passwords in test fixtures

Source: Why did Nock not record all the api requests?


Common Patterns

Pattern 1: Basic Mock Setup

import nock from 'nock';

describe('API Client', () => {
  beforeEach(() => {
    nock.disableNetConnect();
  });

  afterEach(() => {
    nock.cleanAll();
  });

  test('fetches users', async () => {
    const scope = nock('https://api.example.com')
      .get('/users')
      .reply(200, [{ id: 1, name: 'Alice' }]);

    const users = await fetchUsers();

    expect(scope.isDone()).toBe(true);
    expect(users).toHaveLength(1);
  });
});

Pattern 2: Multiple Requests

test('creates and fetches user', async () => {
  const createScope = nock('https://api.example.com')
    .post('/users', { name: 'Alice' })
    .reply(201, { id: 123, name: 'Alice' });

  const fetchScope = nock('https://api.example.com')
    .get('/users/123')
    .reply(200, { id: 123, name: 'Alice' });

  await createUser({ name: 'Alice' });
  const user = await fetchUser(123);

  expect(createScope.isDone()).toBe(true);
  expect(fetchScope.isDone()).toBe(true);
  expect(user.name).toBe('Alice');
});

Pattern 3: Error Response Testing

test('handles 404 error', async () => {
  nock('https://api.example.com')
    .get('/users/999')
    .reply(404, { error: 'User not found' });

  await expect(fetchUser(999)).rejects.toThrow('User not found');
});

Pattern 4: Request Verification

test('sends correct authorization header', async () => {
  const scope = nock('https://api.example.com')
    .get('/users')
    .matchHeader('authorization', 'Bearer token123')
    .reply(200, []);

  await fetchUsers({ token: 'token123' });

  expect(scope.isDone()).toBe(true);
});

Troubleshooting

Issue 1: "NetConnectNotAllowedError: Nock: Disallowed net connect"

Cause: Request doesn't match any mock, and nock.disableNetConnect() is enabled.

Solutions:

  1. Check URL matches exactly (including protocol, host, port, path)
  2. Check HTTP method (GET vs POST vs PUT, etc.)
  3. Check query parameters
  4. Check request headers
  5. Check request body
  6. Use nock.pendingMocks() to see unused mocks
  7. Temporarily allow net connect: nock.enableNetConnect()

Debug:

console.log('Pending mocks:', nock.pendingMocks());
console.log('Active mocks:', nock.activeMocks());

Source: nock GitHub Issues #884 Source: sindresorhus/got Issue #187


Issue 2: "Not all nock interceptors were used"

Cause: Mock defined but request never made.

Solutions:

  1. Verify code actually makes the request
  2. Check for early returns or thrown errors before request
  3. Check async/await usage (missing await?)
  4. Verify test completes (missing done() callback or return promise?)

Debug:

afterEach(() => {
  const pending = nock.pendingMocks();
  if (pending.length > 0) {
    console.error('Unused mocks:', pending);
  }
  nock.cleanAll();
});

Source: Ensure All Nock Interceptors Are Used


Issue 3: Flaky Tests (Intermittent Failures)

Cause: Scope leaks from previous tests.

Solutions:

  1. Add nock.cleanAll() to afterEach
  2. Check for persist() usage
  3. Verify beforeEach resets state
  4. Run tests in isolation to verify

Debug:

beforeEach(() => {
  console.log('Active mocks before test:', nock.activeMocks());
  nock.cleanAll();
});

Source: nock GitHub Issues #705


Issue 4: Recorder Not Capturing Requests

Cause: Various issues with recorder setup.

Solutions:

  1. Ensure nock.recorder.rec() called before requests
  2. Call nock.recorder.play() after requests complete
  3. Use { dont_print: true } to capture output
  4. Call nock.restore() when done recording

Example:

nock.recorder.rec({ output_objects: true, dont_print: true });
await makeRealRequests();
const recordings = nock.recorder.play();
nock.restore();
console.log('Recorded:', recordings);

Source: Why did Nock not record all the api requests?


Version Compatibility

This contract targets nock >=9.0.0. Major changes across versions:

v9.x:

  • Introduced modern API
  • Added disableNetConnect() / enableNetConnect()
  • Improved scope management

v10.x:

  • Enhanced recorder functionality
  • Better TypeScript support

v11.x:

  • Added persist() method
  • Improved error messages

v12.x:

  • Better async/await support
  • Enhanced request matching

v13.x (current):

  • Native ESM support
  • Performance improvements
  • Better error handling

Source: nock changelog


Related Resources

Official Documentation

Tutorials & Guides

Error Handling

Snyk Advisor

Recording & Playback


Summary

nock is a powerful testing tool with a throw-based error model that helps catch API integration issues during testing. The most common errors are:

  1. NetConnectNotAllowedError (40-50% of issues) - Unmatched requests
  2. Scope leaks (30-40% of issues) - Missing cleanup
  3. Unused mocks (20-30% of issues) - Mock not called
  4. Configuration errors (10-20% of issues) - Invalid patterns

Best practices:

  • Always call nock.disableNetConnect() in test setup
  • Always call nock.cleanAll() in afterEach
  • Always verify scope.isDone() after tests
  • Use flexible matchers for dynamic data
  • Sanitize recorded data before committing

Total Sources: 20+ references including official docs, GitHub issues, blog posts, and tutorials.

Last Updated: 2026-02-27

Need a different package?
Request a profile