supertest = function (app){ if ('function' == typeof app) app = http.createServer(app); var obj = {}; methods.forEach(function(method){ obj[method] = function(url){ return new Test(app, method, url); }; }); // Support previous use of del obj.del = obj['delete']; return obj; }
n/a
function Test(app, method, path) { Request.call(this, method.toUpperCase(), path); this.redirects(0); this.buffer(); this.app = app; this._asserts = []; this.url = typeof app === 'string' ? app + path : this.serverAddress(app, path); }
n/a
function TestAgent(app, options) { if (!(this instanceof TestAgent)) return new TestAgent(app, options); if (typeof app === 'function') app = http.createServer(app); // eslint-disable-line no-param-reassign if (options) { this._ca = options.ca; this._key = options.key; this._cert = options.cert; } Agent.call(this); this.app = app; }
...
```js
const request = require('supertest');
const should = require('should');
const express = require('express');
const cookieParser = require('cookie-parser');
describe('request.agent(app)', function() {
const app = express();
app.use(cookieParser());
app.get('/', function(req, res) {
res.cookie('cookie', 'hey');
res.send();
});
...
function Test(app, method, path) { Request.call(this, method.toUpperCase(), path); this.redirects(0); this.buffer(); this.app = app; this._asserts = []; this.url = typeof app === 'string' ? app + path : this.serverAddress(app, path); }
n/a
_assertBody = function (body, res) { var isregexp = body instanceof RegExp; var a; var b; // parsed if (typeof body === 'object' && !isregexp) { try { assert.deepEqual(body, res.body); } catch (err) { a = util.inspect(body); b = util.inspect(res.body); return error('expected ' + a + ' response body, got ' + b, body, res.body); } } else if (body !== res.text) { // string a = util.inspect(body); b = util.inspect(res.text); // regexp if (isregexp) { if (!body.test(res.text)) { return error('expected body ' + b + ' to match ' + body, body, res.body); } } else { return error('expected ' + a + ' response body, got ' + b, body, res.body); } } }
n/a
_assertFunction = function (check, res) { var err; try { err = check(res); } catch (e) { err = e; } if (err instanceof Error) return err; }
n/a
_assertHeader = function (header, res) { var field = header.name; var actual = res.header[field.toLowerCase()]; var fieldExpected = header.value; if (typeof actual === 'undefined') return new Error('expected "' + field + '" header field'); // This check handles header values that may be a String or single element Array if ((actual instanceof Array && actual.toString() === fieldExpected) || fieldExpected === actual) { return; } if (fieldExpected instanceof RegExp) { if (!fieldExpected.test(actual)) { return new Error('expected "' + field + '" matching ' + fieldExpected + ', got "' + actual + '"'); } } else { return new Error('expected "' + field + '" of "' + fieldExpected + '", got "' + actual + '"'); } }
n/a
_assertStatus = function (status, res) { var a; var b; if (res.status !== status) { a = http.STATUS_CODES[status]; b = http.STATUS_CODES[res.status]; return new Error('expected ' + status + ' "' + a + '", got ' + res.status + ' "' + b + '"'); } }
n/a
assert = function (resError, res, fn) { var error; var i; // check for unexpected network errors or server not running/reachable errors // when there is no response and superagent sends back a System Error // do not check further for other asserts, if any, in such case // https://nodejs.org/api/errors.html#errors_common_system_errors var sysErrors = { ECONNREFUSED: 'Connection refused', ECONNRESET: 'Connection reset by peer', EPIPE: 'Broken pipe', ETIMEDOUT: 'Operation timed out' }; if (!res && resError && (resError instanceof Error) && (resError.syscall === 'connect') && (Object.getOwnPropertyNames(sysErrors).indexOf(resError.code) >= 0)) { error = new Error(resError.code + ': ' + sysErrors[resError.code]); fn.call(this, error, null); return; } // asserts for (i = 0; i < this._asserts.length && !error; i += 1) { error = this._assertFunction(this._asserts[i], res); } // set unexpected superagent error if no other error has occurred. if (!error && resError instanceof Error && (!res || resError.status !== res.status)) { error = resError; } fn.call(this, error || null, res); }
n/a
end = function (fn) { var self = this; var server = this._server; var end = Request.prototype.end; end.call(this, function(err, res) { if (server && server._handle) return server.close(assert); assert(); function assert() { self.assert(err, res, fn); } }); return this; }
...
});
request(app)
.get('/user')
.expect('Content-Type', /json/)
.expect('Content-Length', '15')
.expect(200)
.end(function(err, res) {
if (err) throw err;
});
```
Here's an example with mocha, note how you can pass `done` straight to any of the `.expect()` calls:
```js
...
expect = function (a, b, c) { // callback if (typeof a === 'function') { this._asserts.push(a); return this; } if (typeof b === 'function') this.end(b); if (typeof c === 'function') this.end(c); // status if (typeof a === 'number') { this._asserts.push(this._assertStatus.bind(this, a)); // body if (typeof b !== 'function' && arguments.length > 1) { this._asserts.push(this._assertBody.bind(this, b)); } return this; } // header field if (typeof b === 'string' || typeof b === 'number' || b instanceof RegExp) { this._asserts.push(this._assertHeader.bind(this, { name: '' + a, value: b })); return this; } // body this._asserts.push(this._assertBody.bind(this, a)); return this; }
...
app.get('/user', function(req, res) {
res.status(200).json({ name: 'tobi' });
});
request(app)
.get('/user')
.expect('Content-Type', /json/)
.expect('Content-Length', '15')
.expect(200)
.end(function(err, res) {
if (err) throw err;
});
```
...
serverAddress = function (app, path) { var addr = app.address(); var port; var protocol; if (!addr) this._server = app.listen(0); port = app.address().port; protocol = app instanceof https.Server ? 'https' : 'http'; return protocol + '://127.0.0.1:' + port + path; }
n/a
function TestAgent(app, options) { if (!(this instanceof TestAgent)) return new TestAgent(app, options); if (typeof app === 'function') app = http.createServer(app); // eslint-disable-line no-param-reassign if (options) { this._ca = options.ca; this._key = options.key; this._cert = options.cert; } Agent.call(this); this.app = app; }
...
```js
const request = require('supertest');
const should = require('should');
const express = require('express');
const cookieParser = require('cookie-parser');
describe('request.agent(app)', function() {
const app = express();
app.use(cookieParser());
app.get('/', function(req, res) {
res.cookie('cookie', 'hey');
res.send();
});
...
acl = function (url, fn) { // eslint-disable-line no-unused-vars var req = new Test(this.app, method.toUpperCase(), url); req.ca(this._ca); req.cert(this._cert); req.key(this._key); req.on('response', this._saveCookies.bind(this)); req.on('redirect', this._saveCookies.bind(this)); req.on('redirect', this._attachCookies.bind(this, req)); this._attachCookies(req); return req; }
n/a
bind = function (url, fn) { // eslint-disable-line no-unused-vars var req = new Test(this.app, method.toUpperCase(), url); req.ca(this._ca); req.cert(this._cert); req.key(this._key); req.on('response', this._saveCookies.bind(this)); req.on('redirect', this._saveCookies.bind(this)); req.on('redirect', this._attachCookies.bind(this, req)); this._attachCookies(req); return req; }
n/a
checkout = function (url, fn) { // eslint-disable-line no-unused-vars var req = new Test(this.app, method.toUpperCase(), url); req.ca(this._ca); req.cert(this._cert); req.key(this._key); req.on('response', this._saveCookies.bind(this)); req.on('redirect', this._saveCookies.bind(this)); req.on('redirect', this._attachCookies.bind(this, req)); this._attachCookies(req); return req; }
n/a
connect = function (url, fn) { // eslint-disable-line no-unused-vars var req = new Test(this.app, method.toUpperCase(), url); req.ca(this._ca); req.cert(this._cert); req.key(this._key); req.on('response', this._saveCookies.bind(this)); req.on('redirect', this._saveCookies.bind(this)); req.on('redirect', this._attachCookies.bind(this, req)); this._attachCookies(req); return req; }
n/a
copy = function (url, fn) { // eslint-disable-line no-unused-vars var req = new Test(this.app, method.toUpperCase(), url); req.ca(this._ca); req.cert(this._cert); req.key(this._key); req.on('response', this._saveCookies.bind(this)); req.on('redirect', this._saveCookies.bind(this)); req.on('redirect', this._attachCookies.bind(this, req)); this._attachCookies(req); return req; }
n/a
del = function (url, fn) { // eslint-disable-line no-unused-vars var req = new Test(this.app, method.toUpperCase(), url); req.ca(this._ca); req.cert(this._cert); req.key(this._key); req.on('response', this._saveCookies.bind(this)); req.on('redirect', this._saveCookies.bind(this)); req.on('redirect', this._attachCookies.bind(this, req)); this._attachCookies(req); return req; }
n/a
delete = function (url, fn) { // eslint-disable-line no-unused-vars var req = new Test(this.app, method.toUpperCase(), url); req.ca(this._ca); req.cert(this._cert); req.key(this._key); req.on('response', this._saveCookies.bind(this)); req.on('redirect', this._saveCookies.bind(this)); req.on('redirect', this._attachCookies.bind(this, req)); this._attachCookies(req); return req; }
n/a
get = function (url, fn) { // eslint-disable-line no-unused-vars var req = new Test(this.app, method.toUpperCase(), url); req.ca(this._ca); req.cert(this._cert); req.key(this._key); req.on('response', this._saveCookies.bind(this)); req.on('redirect', this._saveCookies.bind(this)); req.on('redirect', this._attachCookies.bind(this, req)); this._attachCookies(req); return req; }
...
```js
const request = require('supertest');
const express = require('express');
const app = express();
app.get('/user', function(req, res) {
res.status(200).json({ name: 'tobi' });
});
request(app)
.get('/user')
.expect('Content-Type', /json/)
.expect('Content-Length', '15')
...
head = function (url, fn) { // eslint-disable-line no-unused-vars var req = new Test(this.app, method.toUpperCase(), url); req.ca(this._ca); req.cert(this._cert); req.key(this._key); req.on('response', this._saveCookies.bind(this)); req.on('redirect', this._saveCookies.bind(this)); req.on('redirect', this._attachCookies.bind(this, req)); this._attachCookies(req); return req; }
n/a
link = function (url, fn) { // eslint-disable-line no-unused-vars var req = new Test(this.app, method.toUpperCase(), url); req.ca(this._ca); req.cert(this._cert); req.key(this._key); req.on('response', this._saveCookies.bind(this)); req.on('redirect', this._saveCookies.bind(this)); req.on('redirect', this._attachCookies.bind(this, req)); this._attachCookies(req); return req; }
n/a
lock = function (url, fn) { // eslint-disable-line no-unused-vars var req = new Test(this.app, method.toUpperCase(), url); req.ca(this._ca); req.cert(this._cert); req.key(this._key); req.on('response', this._saveCookies.bind(this)); req.on('redirect', this._saveCookies.bind(this)); req.on('redirect', this._attachCookies.bind(this, req)); this._attachCookies(req); return req; }
n/a
m-search = function (url, fn) { // eslint-disable-line no-unused-vars var req = new Test(this.app, method.toUpperCase(), url); req.ca(this._ca); req.cert(this._cert); req.key(this._key); req.on('response', this._saveCookies.bind(this)); req.on('redirect', this._saveCookies.bind(this)); req.on('redirect', this._attachCookies.bind(this, req)); this._attachCookies(req); return req; }
n/a
merge = function (url, fn) { // eslint-disable-line no-unused-vars var req = new Test(this.app, method.toUpperCase(), url); req.ca(this._ca); req.cert(this._cert); req.key(this._key); req.on('response', this._saveCookies.bind(this)); req.on('redirect', this._saveCookies.bind(this)); req.on('redirect', this._attachCookies.bind(this, req)); this._attachCookies(req); return req; }
n/a
mkactivity = function (url, fn) { // eslint-disable-line no-unused-vars var req = new Test(this.app, method.toUpperCase(), url); req.ca(this._ca); req.cert(this._cert); req.key(this._key); req.on('response', this._saveCookies.bind(this)); req.on('redirect', this._saveCookies.bind(this)); req.on('redirect', this._attachCookies.bind(this, req)); this._attachCookies(req); return req; }
n/a
mkcalendar = function (url, fn) { // eslint-disable-line no-unused-vars var req = new Test(this.app, method.toUpperCase(), url); req.ca(this._ca); req.cert(this._cert); req.key(this._key); req.on('response', this._saveCookies.bind(this)); req.on('redirect', this._saveCookies.bind(this)); req.on('redirect', this._attachCookies.bind(this, req)); this._attachCookies(req); return req; }
n/a
mkcol = function (url, fn) { // eslint-disable-line no-unused-vars var req = new Test(this.app, method.toUpperCase(), url); req.ca(this._ca); req.cert(this._cert); req.key(this._key); req.on('response', this._saveCookies.bind(this)); req.on('redirect', this._saveCookies.bind(this)); req.on('redirect', this._attachCookies.bind(this, req)); this._attachCookies(req); return req; }
n/a
move = function (url, fn) { // eslint-disable-line no-unused-vars var req = new Test(this.app, method.toUpperCase(), url); req.ca(this._ca); req.cert(this._cert); req.key(this._key); req.on('response', this._saveCookies.bind(this)); req.on('redirect', this._saveCookies.bind(this)); req.on('redirect', this._attachCookies.bind(this, req)); this._attachCookies(req); return req; }
n/a
notify = function (url, fn) { // eslint-disable-line no-unused-vars var req = new Test(this.app, method.toUpperCase(), url); req.ca(this._ca); req.cert(this._cert); req.key(this._key); req.on('response', this._saveCookies.bind(this)); req.on('redirect', this._saveCookies.bind(this)); req.on('redirect', this._attachCookies.bind(this, req)); this._attachCookies(req); return req; }
n/a
options = function (url, fn) { // eslint-disable-line no-unused-vars var req = new Test(this.app, method.toUpperCase(), url); req.ca(this._ca); req.cert(this._cert); req.key(this._key); req.on('response', this._saveCookies.bind(this)); req.on('redirect', this._saveCookies.bind(this)); req.on('redirect', this._attachCookies.bind(this, req)); this._attachCookies(req); return req; }
n/a
patch = function (url, fn) { // eslint-disable-line no-unused-vars var req = new Test(this.app, method.toUpperCase(), url); req.ca(this._ca); req.cert(this._cert); req.key(this._key); req.on('response', this._saveCookies.bind(this)); req.on('redirect', this._saveCookies.bind(this)); req.on('redirect', this._attachCookies.bind(this, req)); this._attachCookies(req); return req; }
n/a
post = function (url, fn) { // eslint-disable-line no-unused-vars var req = new Test(this.app, method.toUpperCase(), url); req.ca(this._ca); req.cert(this._cert); req.key(this._key); req.on('response', this._saveCookies.bind(this)); req.on('redirect', this._saveCookies.bind(this)); req.on('redirect', this._attachCookies.bind(this, req)); this._attachCookies(req); return req; }
...
});
```
Anything you can do with superagent, you can do with supertest - for example multipart file uploads!
```js
request(app)
.post('/')
.field('name', 'my awesome avatar')
.attach('avatar', 'test/fixtures/homeboy.jpg')
...
```
Passing the app or url each time is not necessary, if you're testing
the same host you may simply re-assign the request variable with the
...
propfind = function (url, fn) { // eslint-disable-line no-unused-vars var req = new Test(this.app, method.toUpperCase(), url); req.ca(this._ca); req.cert(this._cert); req.key(this._key); req.on('response', this._saveCookies.bind(this)); req.on('redirect', this._saveCookies.bind(this)); req.on('redirect', this._attachCookies.bind(this, req)); this._attachCookies(req); return req; }
n/a
proppatch = function (url, fn) { // eslint-disable-line no-unused-vars var req = new Test(this.app, method.toUpperCase(), url); req.ca(this._ca); req.cert(this._cert); req.key(this._key); req.on('response', this._saveCookies.bind(this)); req.on('redirect', this._saveCookies.bind(this)); req.on('redirect', this._attachCookies.bind(this, req)); this._attachCookies(req); return req; }
n/a
purge = function (url, fn) { // eslint-disable-line no-unused-vars var req = new Test(this.app, method.toUpperCase(), url); req.ca(this._ca); req.cert(this._cert); req.key(this._key); req.on('response', this._saveCookies.bind(this)); req.on('redirect', this._saveCookies.bind(this)); req.on('redirect', this._attachCookies.bind(this, req)); this._attachCookies(req); return req; }
n/a
put = function (url, fn) { // eslint-disable-line no-unused-vars var req = new Test(this.app, method.toUpperCase(), url); req.ca(this._ca); req.cert(this._cert); req.key(this._key); req.on('response', this._saveCookies.bind(this)); req.on('redirect', this._saveCookies.bind(this)); req.on('redirect', this._attachCookies.bind(this, req)); this._attachCookies(req); return req; }
n/a
rebind = function (url, fn) { // eslint-disable-line no-unused-vars var req = new Test(this.app, method.toUpperCase(), url); req.ca(this._ca); req.cert(this._cert); req.key(this._key); req.on('response', this._saveCookies.bind(this)); req.on('redirect', this._saveCookies.bind(this)); req.on('redirect', this._attachCookies.bind(this, req)); this._attachCookies(req); return req; }
n/a
report = function (url, fn) { // eslint-disable-line no-unused-vars var req = new Test(this.app, method.toUpperCase(), url); req.ca(this._ca); req.cert(this._cert); req.key(this._key); req.on('response', this._saveCookies.bind(this)); req.on('redirect', this._saveCookies.bind(this)); req.on('redirect', this._attachCookies.bind(this, req)); this._attachCookies(req); return req; }
n/a
search = function (url, fn) { // eslint-disable-line no-unused-vars var req = new Test(this.app, method.toUpperCase(), url); req.ca(this._ca); req.cert(this._cert); req.key(this._key); req.on('response', this._saveCookies.bind(this)); req.on('redirect', this._saveCookies.bind(this)); req.on('redirect', this._attachCookies.bind(this, req)); this._attachCookies(req); return req; }
n/a
subscribe = function (url, fn) { // eslint-disable-line no-unused-vars var req = new Test(this.app, method.toUpperCase(), url); req.ca(this._ca); req.cert(this._cert); req.key(this._key); req.on('response', this._saveCookies.bind(this)); req.on('redirect', this._saveCookies.bind(this)); req.on('redirect', this._attachCookies.bind(this, req)); this._attachCookies(req); return req; }
n/a
trace = function (url, fn) { // eslint-disable-line no-unused-vars var req = new Test(this.app, method.toUpperCase(), url); req.ca(this._ca); req.cert(this._cert); req.key(this._key); req.on('response', this._saveCookies.bind(this)); req.on('redirect', this._saveCookies.bind(this)); req.on('redirect', this._attachCookies.bind(this, req)); this._attachCookies(req); return req; }
n/a
unbind = function (url, fn) { // eslint-disable-line no-unused-vars var req = new Test(this.app, method.toUpperCase(), url); req.ca(this._ca); req.cert(this._cert); req.key(this._key); req.on('response', this._saveCookies.bind(this)); req.on('redirect', this._saveCookies.bind(this)); req.on('redirect', this._attachCookies.bind(this, req)); this._attachCookies(req); return req; }
n/a
unlink = function (url, fn) { // eslint-disable-line no-unused-vars var req = new Test(this.app, method.toUpperCase(), url); req.ca(this._ca); req.cert(this._cert); req.key(this._key); req.on('response', this._saveCookies.bind(this)); req.on('redirect', this._saveCookies.bind(this)); req.on('redirect', this._attachCookies.bind(this, req)); this._attachCookies(req); return req; }
n/a
unlock = function (url, fn) { // eslint-disable-line no-unused-vars var req = new Test(this.app, method.toUpperCase(), url); req.ca(this._ca); req.cert(this._cert); req.key(this._key); req.on('response', this._saveCookies.bind(this)); req.on('redirect', this._saveCookies.bind(this)); req.on('redirect', this._attachCookies.bind(this, req)); this._attachCookies(req); return req; }
n/a
unsubscribe = function (url, fn) { // eslint-disable-line no-unused-vars var req = new Test(this.app, method.toUpperCase(), url); req.ca(this._ca); req.cert(this._cert); req.key(this._key); req.on('response', this._saveCookies.bind(this)); req.on('redirect', this._saveCookies.bind(this)); req.on('redirect', this._attachCookies.bind(this, req)); this._attachCookies(req); return req; }
n/a