Created
June 14, 2014 21:38
-
-
Save grncdr/6065f3448a73ae364706 to your computer and use it in GitHub Desktop.
testing API's with buster
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'use strict'; | |
var buster = require('buster'); | |
var testApi = require('./test-http'); | |
function exampleApp () { | |
return function (req, res) { | |
res.setHeader('content-type', 'text/plain'); | |
res.setHeader('content-length', req.url.length); | |
res.end(req.url); | |
}; | |
} | |
buster.testCase('Echo server', testApi(exampleApp, { | |
// You can use `this.request(path, options)` in setUp | |
setUp: function () { | |
this.expectedContentType = 'text/plain'; | |
}, | |
// Using tearDown to assert common post-conditions | |
tearDown: function () { | |
if (this.response) { | |
buster.assert.equals(this.response.headers['content-type'], | |
this.expectedContentType, | |
'Maybe you need to set this.expectedContentType in your test?'); | |
} | |
}, | |
'GET /a/static/path': function (response) { | |
// Use an argument, or not. | |
buster.assert.same(this.response, response); | |
buster.assert.equals('/a/static/path', response.body); | |
}, | |
'GET /a/:parameterized/path': { | |
// use getParams on individual requests. This can also return a promise. | |
getParams: function () { | |
return { parameterized: 'something' }; | |
}, | |
assertions: function (response) { | |
buster.assert.equals(response.body, '/a/something/path'); | |
} | |
} | |
})); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'use strict'; | |
var http = require('http'); | |
var url = require('url'); | |
var Promise = require('bluebird'); | |
var questor = require('questor'); | |
var buster = require('buster'); | |
module.exports = function testHttpApp (createApp, tests) { | |
Object.keys(tests).forEach(function (key) { | |
var match = key.match(/^(GET|PUT|POST|DELETE|HEAD) (\/[^ ]*)$/); | |
if (match) { | |
var test = createRequestTest(createApp, match[1], match[2], tests[key]); | |
tests[test.testName || key] = test; | |
} | |
}); | |
tests.setUp = before(tests.setUp, function (next) { | |
var self = this; | |
this.app = createApp(); | |
this.server = http.createServer(this.app) | |
.listen(0, 'localhost') | |
.on('listening', function () { | |
var port = self.server.address().port; | |
self.request = function (path, options) { | |
var uri = url.format({ | |
hostname: 'localhost', | |
port: port, | |
protocol: 'http:', | |
pathname: path | |
}); | |
return questor(uri, options); | |
}; | |
next(); | |
}); | |
}); | |
tests.tearDown = before(tests.tearDown, function (next) { | |
this.server.close(); | |
this.server.on('close', next); | |
}); | |
return tests; | |
}; | |
function createRequestTest (createApp, method, path, test) { | |
return function () { | |
var self = this; | |
if (typeof test !== 'object' || !test.assertions) { | |
test = { | |
assertions: test | |
}; | |
} | |
var params = test.getParams ? test.getParams.call(this) : {}; | |
return Promise.resolve(params).then(function (params) { | |
if (params) { | |
path = path.replace(/:(\w+)/g, function (_, name) { | |
if (name in params) { | |
return params[name]; | |
} else { | |
throw new Error('Parameter not defined: ' + name); | |
} | |
}); | |
} | |
var options = { method: method }; | |
if (test.headers) { options.headers = test.headers; } | |
if (test.body) { options.body = test.body; } | |
return self.request(path, options).then(function (response) { | |
self.response = response; | |
return checkResponse(self, test.assertions, response); | |
}); | |
}); | |
}; | |
} | |
function checkResponse (test, assertions, response) { | |
if (typeof assertions === 'function') { | |
return assertions.call(test, response); | |
} | |
if (Array.isArray(assertions)) { | |
return Promise.reduce(assertions, function (_, assertion) { | |
return assertion.call(test, response).return(_); | |
}); | |
} | |
if (typeof assertions === 'object') { | |
buster.assert.match(response, assertions); | |
} | |
} | |
function before (original, first) { | |
return function (done) { | |
var self = this; | |
first.call(self, function () { | |
if (original) { | |
original.call(self, done); | |
if (!original.length) { | |
done(); | |
} | |
} else { | |
done(); | |
} | |
}); | |
}; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment