supertest-as-promised
SuperTest as Promised supercharges SuperTest with a then
method.
Instead of layering callbacks on callbacks in your tests:
request(app)
.get("/user")
.expect(200, function (err, res) {
if (err) return done(err);
var userId = res.body.id;
request(app)
.post("/kittens")
.send({ userId: userId, ... })
.expect(201, function (err, res) {
if (err) return done(err);
// ...
});
});
chain your requests like you were promised:
return request(app)
.get("/user")
.expect(200)
.then(function (res) {
return request(app)
.post("/kittens")
.send({ userId: res})
.expect(201);
})
.then(function (res) {
// ...
});
Usage
SuperTest as Promised operates just like normal SuperTest, except that the
object returned by .get
, .post
, etc. is a proper
thenable:
var express = require("express")
, request = require("supertest-as-promised");
var app = express();
request(app)
.get("/kittens")
.expect(200)
.then(function (res) {
// ...
});
If you use a promise-friendly test runner, you can just
return your request
chain from the test case rather than messing with a
callback:
describe("GET /kittens", function () {
it("should work", function () {
return request(app).get("/kittens").expect(200);
});
});
Agents
If you use a SuperTest agent to persist cookies, those are thenable too:
var agent = require("supertest-as-promised").agent(app);
agent
.get("/ugly-kitteh")
.expect(404)
.then(function () {
// ...
})
Promisey goodness
To start, only the then
and catch
methods are exposed. But once you've
called .then
or .catch
once, you've got a proper Bluebird promise that
supports the whole gamut of promisey goodness:
request(app)
.get("/kittens")
.expect(201)
.then(function (res) { /* ... */ })
// I'm a real promise now!
.catch(function (err) { /* ... */ })
See the Bluebird API for everything that's available.
You may find it cleaner to cast directly to a promise using the toPromise
method:
request(app)
.get("/kittens")
.expect(201)
.toPromise()
// I'm a real promise now!
.delay(10)
.then(function (res) { /* ... */ })
BYOP: Bring your own Promise
You can supply own promise library so that the promises returned have your convenience methods of choice.
Simply call the SuperTest as Promised module with a ES6-compliant Promise
constructor, and you'll get back a new module configured to return your custom
promises. To swap in when.js, for example:
var when = require("when")
, request;
request = require("supertest-as-promised")(when.Promise);
request(app)
.get("/when.js")
.then(function (res) { /* ... */ })
// I'm a when.js promise! (instanceof when.Promise == true)
.frobulate()
request = require("supertest-as-promised");
request(app)
.get("/bluebird.js")
.then(function (res) { /* .. */ })
// I'm back to the default Bluebird promise!
Debugging
Suppose your snazzy test
it("should get kittens", function () {
return request(app).get("/kittens").expect(200)
.then(function (res) {
return expect(res.body).to.equal("kittens r cute!");
});
});
suddenly starts failing with a "400 Bad Request" error. It'd sure be
handy if you could print out the response body to see if the server
mentioned what, in particular, was bad about your test. Chain on a
.catch
and inspect err.response
:
it("should get kittens", function () {
return request(app).get("/kittens").expect(200)
.then(function (res) {
return expect(res.text).to.equal("kittens r cute!");
})
.catch(function (err) {
console.log(err.response.text); // "You have viewed too many kittens today."
});
});
Installation
Node
$ npm install supertest supertest-as-promised
SuperTest as Promised lists supertest
as a
peer dependency, so it'll wrap whatever version of SuperTest
you've asked for in your own package.json
.
In earlier versions of NPM, failing to list SuperTest as a dependency would get you the latest version. In NPM 3, failing to list SuperTest as a dependency will generate a warning and SuperTest will not be installed.
Do note that SuperTest as Promised is a well-behaved citizen and doesn't monkey-patch SuperTest directly:
// I return thenables!
var request = require("supertest-as-promised");
// I'm lame and force you to use callbacks
var request = require("supertest");
Versions
We follow semver: the major version number will be upgraded with any breaking change. Breaking changes in each major version are listed below. Consult the changelog for a list of meaningful new features in each version; consult the commit log for a complete list.
Breaking changes in 4.0
- In
.catch
handlers,err.response
is now marked as non-enumerable.
Breaking changes in 3.0
- Bluebird has been upgraded to version 3.3.1.
Breaking changes in 2.0
- Bluebird has been upgraded to version 2.9.24.