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