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 vs. JS Animation: Which is Faster?

    How is it possible that JavaScript-based animation has secretly always been as fast — or faster — than CSS transitions? And, how is it possible that Adobe and Google consistently release media-rich mobile sites that rival the performance of native apps? This article serves as a point-by-point...

  • By
    Introducing MooTools Templated

    One major problem with creating UI components with the MooTools JavaScript framework is that there isn't a great way of allowing customization of template and ease of node creation. As of today, there are two ways of creating: new Element Madness The first way to create UI-driven...

Incredible Demos

  • By
    Create a Photo Stack Effect with Pure CSS Animations or MooTools

    My favorite technological piece of Google Plus is its image upload and display handling.  You can drag the images from your OS right into a browser's DIV element, the images upload right before your eyes, and the albums page displays a sexy photo deck animation...

  • By
    Introducing MooTools LazyLoad

    Once concept I'm very fond of is lazy loading. Lazy loading defers the loading of resources (usually images) until they are needed. Why load stuff you never need if you can prevent it, right? I've created LazyLoad, a customizable MooTools plugin that...

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!