Desenvolvimento

20 out, 2015

Interceptando requisições HTTP com o nock do Node.js

Publicidade

Fazer testes unitários de APIs externas é difícil, não importa a linguagem que você vai usar. Bom, trabalhar com qualquer API externa é assustador, seja porque você tem zero controle dos problemas de rede, das mudanças na API, ou por uma série de outras questões. Mas se você criar um serviço que se baseia em dados de outro servidor, ainda é importante criar testes de unidade que dependam de outro serviço.

Se você estiver usando um serviço de terceiros, criar testes unitários é realmente difícil… até você descobrir nock, uma biblioteca do Node que intercepta requisições e permite responder a elas como você deseja, incluindo o envio de respostas automáticas com códigos e payloads.

Obtendo o nock

Como cada pacote do Node, você tem que instalá-lo primeiro:

npm install nock

 

Uma vez instalado, faça a requisição em seu script:

var nock = require('nock');

Essa é a configuração.

Usando o nock

O uso mais básico de nock é interceptar uma requisição GET para uma determinada URL:

nock('http://davidwalsh.name')
	.get('/users/22').reply(200, {
		username: 'davidwalshblog',
		firstname: 'David'
	});

nock('http://davidwalsh.name')
	.get('/content/homepage')
	.reply(200, 'This is the HTML for the homepage');

nock('http://davidwalsh.name')
	.get('/content/page-no-exist')
	.reply(404, 'This page could not be found');

O exemplo acima intercepta um pedido GET para um dado host + path e responde com um código de resposta e os conteúdos. Você também pode interceptar requisições POST:

nock('http://davidwalsh.name')
	.post('/users/detail')
	.reply(200, {
		firstname: 'David'
	});

Você também pode diminuir as combinações GET e POST definindo as strings de queries:

nock('http://davidwalsh.name')
	.post('/users/detail', { username: 'davidwalshblog' })
	.reply(200, {
		firstname: 'David'
	});

Se responder com headers é importante, você pode fazer isso também:

var scope = nock('http://davidwalsh.name')
	.get('/')
	.reply(200, 'Hello World!', {
		'X-My-Headers': 'My Header value'
	});

Se você quiser fazer alguma lógica de processamento avançado antes de responder à requisição, você pode responder com uma função em vez disso:

nock('http://davidwalsh.name')
	.post('/users/detail', { username: 'davidwalshblog' })
	.reply(function() {

		// Some logic

		return [200, resultingContent];
	});

Então por que tudo isso é importante? Se você fizer qualquer teste baseado em serviço dentro Node.js, incluindo qualquer coisa de HTTP para testes locais de db/serviço, você vai estar desesperado para que algo intercepte as requests reais em vez de tentar métodos tapa-buraco ou usar outras soluções burras. Em suma: o seu app pode funcionar como de costume durante os testes, o nock vai interceptar esses pedidos e jogar de volta o que você quer!

E o que é impressionante sobre o nock? Este artigo fala do básico do nock. Para um projeto em que estou trabalhando, chamado Discord, eu criei um conjunto de testes que roda em… nock. Eu criei uma gravação que salvou requisições e suas respostas, economizando grande quantidade de trabalho manual.

Conheça nock! E me agradeça no Twitter quando você fizer isso!

***

David Walsh faz parte do time de colunistas internacionais do iMasters. A tradução do artigo é feita pela redação iMasters, com autorização do autor, e você pode acompanhar o artigo em inglês no link: http://davidwalsh.name/nock