Intercept HTTP Requests with Node.js nock
Unit testing external APIs is difficult no matter what language you do it in. Hell, working with any external API is scary, if only because you have zero control of networking issues, API changes, and a host of other issues. But if you do create a service which relies on another host's data, it's still important to create unit tests that rely on the other service.
If you're using a third party service, creating unit tests is really tough...until you discover nock, a node module which intercepts requests and allows you to respond to them as you wish, including sending back custom response codes and payloads. Let me show you how to use nock!
Getting nock
Like every node package, you have to install it first:
npm install nock
Once installed, required it in your script:
var nock = require('nock');
That's the setup.
Using nock
The most basic usage of nock is intercepting a GET request to a given URL:
nock('https://davidwalsh.name') .get('/users/22').reply(200, { username: 'davidwalshblog', firstname: 'David' }); nock('https://davidwalsh.name') .get('/content/homepage') .reply(200, 'This is the HTML for the homepage'); nock('https://davidwalsh.name') .get('/content/page-no-exist') .reply(404, 'This page could not be found');
The example above intercepts a GET request to a given host + path and responds with a desired response code and contents. You can intercept POST requests as well:
nock('https://davidwalsh.name') .post('/users/detail') .reply(200, { firstname: 'David' });
You can also narrow down GET and POST matches by setting the data or query strings:
nock('https://davidwalsh.name') .post('/users/detail', { username: 'davidwalshblog' }) .reply(200, { firstname: 'David' });
If responding with given headers is important, you can do that too:
var scope = nock('https://davidwalsh.name') .get('/') .reply(200, 'Hello World!', { 'X-My-Headers': 'My Header value' });
If you want to do some advanced processing logic before responding to the request, you can reply with a function instead:
nock('https://davidwalsh.name') .post('/users/detail', { username: 'davidwalshblog' }) .reply(function() { // Some logic return [200, resultingContent]; });
So why is all of this important? If you do any service-based testing within Node.js, including anything from HTTP to local db/service testing, you'll be desperate for a utility that can intercept real requests instead of attempting to monkey patch request methods or use other gross workarounds. In short: your app can function as usual during testing, nock intercepts those requests and throws back what you want!
And what's awesome about nock? This post touches the very basics of nock. For a project I'm working on called Discord, I've created a test suite which runs off of tests recorded by...nock. I created a recorded which saved requests and their responses, saving us loads of manual labor.
Get to know nock! And thank me on Twitter when you're done!
is it only intercepting node’s requests? I was great if it could intercept all request even from borwsers
Nock is awesome! @joe you need to use a tool such as Fiddler for that