Jake Pruitt

This is where I write.

← Home

Nock

When testing the API for zamano-api, a small Node.js wrapper around the Zamano mobile messaging platform, I ran into the problem of finding a good library to test my requests against. I needed something that would pretend to be a server for the HTTP API I was calling, and simply respond with some XML that I would parse into a JavaScript object. After looking extensively at Sinon.JS, I realized that Sinon just had too many features. I just wanted to mock an HTTP endpoint.

The best solution I found was nock, an HTTP mocking and expectations library by Pedro Teixeira, the author of Professional Node.js (the best Node.js book I have read yet). Nock is small, has a beautiful chaining API, and has some handy sugaring.

If you want to see how I used nock, check it out on GitHub. This article walks through my small usage.

Nock Once, Nock Twice

The first part of setting up a URL for nock to mock is passing that URL to the nock function:

var nock = require('nock')

var scope = nock('http://api.webservice.com')

Now, the next time you call http://api.webservice.com, the request will not go out to the actual website, but will be intercepted by nock. This will only work once though; if you try to call it more than once, the actual server will be called. To get around this, you can specify the number of times you would like nock to respond with the times method:

var nock = require('nock')
var http = require('http')

var scope = nock('http://api.webservice.com')
	.get('/')
	.times(2)
	.reply(200, 'Ok')

http.get('http://api.webservice.com') // respond body "Ok"
http.get('http://api.webservice.com') // respond body "Ok"
http.get('http://api.webservice.com') // respond with api.webservice.com result

Or if we want the response to continue for all calls, we use the persist method:

var scope = nock('http://api.webservice.com')
	.get('/')
	.persist()
	.reply(200, 'Always Ok')

Reply Away

There are a lot of options for the way you can reply to a request with nock. The easiest way mentioned above is just with a string, but you can also reply with a JSON encoded object, or even a file:

var scope = nock('http://api.webservice.com')
	.get('/withstring')
	.reply(200, 'Hello String')
	.get('/withJSON')
	.reply(200, {
		id: 1000101,
		country: 'US'
	})
	.get('/withfile')
	.reply(200, __dirname + '/testXML/success.xml')

Also notice in that example that we could set up multiple URLs with just one chained nock call. I personally think this API is super elegant and provided exactly what I needed.

What do you use for mocking HTTP? Any tools you would like to learn more about? Comment below or shout out to me on Twitter @thejakepruitt.