Intercept HTTP Requests with Node.js nock

By  on  

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!

Recent Features

  • By
    CSS @supports

    Feature detection via JavaScript is a client side best practice and for all the right reasons, but unfortunately that same functionality hasn't been available within CSS.  What we end up doing is repeating the same properties multiple times with each browser prefix.  Yuck.  Another thing we...

  • By
    5 HTML5 APIs You Didn’t Know Existed

    When you say or read "HTML5", you half expect exotic dancers and unicorns to walk into the room to the tune of "I'm Sexy and I Know It."  Can you blame us though?  We watched the fundamental APIs stagnate for so long that a basic feature...

Incredible Demos

  • By
    Fullscreen API

    As we move toward more true web applications, our JavaScript APIs are doing their best to keep up.  One very simple but useful new JavaScript API is the Fullscreen API.  The Fullscreen API provides a programmatic way to request fullscreen display from the user, and exit...

  • By
    The Simple Intro to SVG Animation

    This article serves as a first step toward mastering SVG element animation. Included within are links to key resources for diving deeper, so bookmark this page and refer back to it throughout your journey toward SVG mastery. An SVG element is a special type of DOM element...

Discussion

  1. Joe

    is it only intercepting node’s requests? I was great if it could intercept all request even from borwsers

  2. Nock is awesome! @joe you need to use a tool such as Fiddler for that

Wrap your code in <pre class="{language}"></pre> tags, link to a GitHub gist, JSFiddle fiddle, or CodePen pen to embed!