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
    Welcome to My New Office

    My first professional web development was at a small print shop where I sat in a windowless cubical all day. I suffered that boxed in environment for almost five years before I was able to find a remote job where I worked from home. The first...

  • By
    Being a Dev Dad

    I get asked loads of questions every day but I'm always surprised that they're rarely questions about code or even tech -- many of the questions I get are more about non-dev stuff like what my office is like, what software I use, and oftentimes...

Incredible Demos

  • By
    jQuery Chosen Plugin

    Without a doubt, my least favorite form element is the SELECT element.  The element is almost unstylable, looks different across platforms, has had inconsistent value access, and disaster that is the result of multiple=true is, well, a disaster.  Needless to say, whenever a developer goes...

  • By
    Create Twitter-Style Dropdowns Using jQuery

    Twitter does some great stuff with JavaScript. What I really appreciate about what they do is that there aren't any epic JS functionalities -- they're all simple touches. One of those simple touches is the "Login" dropdown on their homepage. I've taken...

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!