Nock: Intercept and Mock Node.js HTTP Requests
Nock acts like a fake switchboard for your Node.js app's outgoing HTTP calls, redirecting them to pre-defined responses. This lets you unit test code that relies on external services, making tests fast, deterministic, and offline-capable.
WHY IT EXISTS: Unit tests should be fast, reliable, and isolated. When your code makes a real HTTP request to an external API, your test becomes slow, dependent on network connectivity, and subject to the API's availability. This makes tests flaky and hard to run consistently. Nock was created to solve this by removing the network from the equation for testing purposes.
THE MENTAL MODEL: Nock acts like a switchboard operator for your app's network calls. It works by patching Node.js's native http and https modules. When your code attempts to make an outbound request, Nock intercepts it before it ever hits the network. It checks if the request's method, host, path, and body match any of your predefined interceptors. If it finds a match, it returns the mock response you specified. If not, it throws an error by default.
HOW IT WORKS: You define mocks by chaining methods. A typical mock looks like this: nock('http://api.example.com').get('/users/1').reply(200, { id: 1, name: 'Test User' });. First, you specify the base URL with nock(). Then, you chain the HTTP verb like .get() or .post(), providing the path. You can also specify required headers or body contents. Finally, you define the desired response with .reply(), providing a status code and a body. Nock then waits for your application code to make a matching request during the test.
WHEN TO USE IT: Use Nock in unit and integration tests for any code that makes HTTP requests. This is ideal for testing a service that fetches data from a third-party API, a payment gateway integration, or a client for your own microservices. It ensures your tests validate only your code's logic, not the external service's uptime or data.
WHEN NOT TO USE IT: Avoid Nock for true end-to-end (E2E) tests. The purpose of E2E tests is to verify the entire system works together, including real network calls and live external services. Using mocks here would invalidate the test's goal. Also, if your mock definitions become significantly more complex than the code you're testing, it may be a sign of a poor component design.
ONE CANONICAL EXAMPLE: Imagine testing a function fetchUser(userId) that uses a library like axios to get data. Your test would first set up the mock: nock('https://api.myapp.com').get('/users/123').reply(200, { id: 123, name: 'Alice' });. Then, your test would execute await fetchUser(123) and assert that the returned data matches the mock body. Finally, you can call nock.isDone() to verify that the mock was actually used, preventing false positives.
Read the original → github.com
Get five bites like this every day.
Tezvyn delivers a daily feed of 60-second tech bites with quizzes to lock in what you learn.