I found it surpisingly difficult to find sample code testing an a hapi.js service that makes a web request to another service. So I'll share what I came up with, you can find the full working code here https://gist.github.com/robjoh/41e76afd82656db54be9
The server
This server simply makes a call to http://date.jsontest.com and returns the date from the response.
var Hapi = require('hapi')
var Boom = require('boom');
var request = require('request');
var server = module.exports = new Hapi.Server();
server.connection({
host: 'localhost',
port: 8080
});
server.route({
path: '/',
method: 'GET',
handler: function(req, reply) {
request.get('http://date.jsontest.com', function(err, response, content) {
if (err) {
return reply(Boom.wrap(err));
}
switch(response.statusCode) {
case 200:
return reply(JSON.parse(content).date);
case 404:
return reply(Boom.notFound());
default:
return reply(Boom.create(500));
}
});
}
});
if (!module.parent) {
server.start(function() {
console.log('started');
});
}
Setting up the test
In addition to Lab and Code, I'm using the Sinon mock/spy framework to intercept the request.get
function. I make sure to restore request.get
to it's previous implementation after each test.
describe('server', function() {
var options = {
url: '/',
method: 'GET'
};
var requestStub;
beforeEach(function(done) {
requestStub = Sinon.stub(request, 'get');
done();
});
afterEach(function(done) {
requestStub.restore();
done();
});
});
Testing the 404 case
To verify the 404 response case, I simply tell the stub to return a response with a 404 status.
it('handles a 404 status', function(done) {
requestStub.yields(null, {statusCode: 404});
server.inject(options, function(response) {
expect(response.statusCode).to.equal(404);
done();
});
});
Testing the happy path
In these tests, I want to verify that I am calling the service as expected.
The first test verifies the request. In it I grab the value supplied by the request.get call from the service.
The second test is verifies the response this server emits which should be a 200 with the date as content.
it('makes the request', function(done) {
requestStub.yields(null, {statusCode: 200}, '{}');
server.inject(options, function(response) {
//arg[0] is url from request.get(url, function)
var requestUrl = requestStub.getCall(0).args[0];
expect(requestUrl).to.equal('http://date.jsontest.com');
done();
});
});
it('returns the date', function(done) {
requestStub.yields(null, {statusCode: 200}, JSON.stringify({date: '02-17-2015'}));
server.inject(options, function(response) {
expect(response.statusCode).to.equal(200);
expect(response.result).to.equal('02-17-2015');
done();
});
})