diff --git a/README.md b/README.md index 8a1765a..19ecc85 100644 --- a/README.md +++ b/README.md @@ -87,6 +87,21 @@ You can optionally send a ReadableStream with reply, for example testing with la req.reply(statusCode, new RandomStream(10000), responseHeaders); ``` +You can also provide functions instead of concrete values. These functions will be called with the matching incoming http request, and it useful in cases where the response body or headers need to be constructed based on the incoming request data: + +```Javascript + // returns the current hockServer instance + req.reply( + statusCode, + function replyWithBody(request) { + return body; + }, + function replyWithHeaders(request) { + return responseHeaders; + } + ); +``` + ## Multiple matching requests You can optionally tell hock to match multiple requests for the same route: diff --git a/lib/hock.js b/lib/hock.js index f76a010..c3efe49 100644 --- a/lib/hock.js +++ b/lib/hock.js @@ -394,7 +394,7 @@ Hock.prototype.handler = function (req, res) { res.end('No Matching Response!\n'); } else { - if (self._assertions[matchIndex].sendResponse(res)) { + if (self._assertions[matchIndex].sendResponse(req, res)) { self._assertions.splice(matchIndex, 1)[0]; } if (self._assertions.length === 0) self.emit('done'); diff --git a/lib/request.js b/lib/request.js index d5350f8..dd849a2 100644 --- a/lib/request.js +++ b/lib/request.js @@ -24,10 +24,11 @@ function bodyEqual(a, b) { } } -function createResponse(response) { +function createResponse(request, response) { var self = this; - var headers = this.response.headers || this._defaultReplyHeaders; + var headers = typeof this.response.headers === 'function' ? this.response.headers(request) : this.response.headers || this._defaultReplyHeaders; + this.response.body = typeof this.response.body === 'function' ? this.response.body(request) : this.response.body; response.writeHead(this.response.statusCode, headers); @@ -305,19 +306,20 @@ Request.prototype.isMatch = function(request) { * * @description send the response to the provided Hock response. Applies a delay if it was set * + * @param {object} request The request object from the hock server * @param {object} response The response object from the hock server */ -Request.prototype.sendResponse = function(response) { +Request.prototype.sendResponse = function(request, response) { var self = this; this._count++; if (this._delay > 0) { setTimeout(function() { - createResponse.call(self, response); + createResponse.call(self, request, response); }, this._delay); } else { - createResponse.call(this, response); + createResponse.call(this, request, response); } return this.shouldPrune(); diff --git a/test/simple-test.js b/test/simple-test.js index 3f22c05..d79b41f 100644 --- a/test/simple-test.js +++ b/test/simple-test.js @@ -1,4 +1,5 @@ var http = require('http'), + url = require('url'), should = require('should'), shouldHttp = require('should-http'), request = require('request'), @@ -191,6 +192,45 @@ describe('Hock HTTP Tests', function() { }); }); + it('should work with response body function', function(done) { + hockInstance + .get('/url?key=value') + .reply(200, function(request) { + const query = url.parse(request.url, true).query; + return { 'hock': 'ok', key: query.key }; + }); + + request('http://localhost:' + PORT + '/url?key=value', function(err, res, body) { + should.not.exist(err); + should.exist(res); + res.statusCode.should.equal(200); + JSON.parse(body).should.eql({ 'hock': 'ok', key: 'value' }); + + done(); + }); + }); + + it('should work with response header function', function(done) { + hockInstance + .get('/url?key=value') + .reply(200, { 'hock': 'ok' }, function(request) { + const query = url.parse(request.url, true).query; + return { + 'x-request-key': query.key, + }; + }); + + request('http://localhost:' + PORT + '/url?key=value', function(err, res, body) { + should.not.exist(err); + should.exist(res); + res.statusCode.should.equal(200); + + res.headers['x-request-key'].should.eql('value'); + + done(); + }); + }); + after(function (done) { httpServer.close(done); });