Question - Can supertest be promisified simply using PromisifyAll?
nareshbhatia opened this issue · comments
I am wondering if there is the difference between supertest-as-promised vs. the following 3 lines of code:
var request = require('supertest');
var Promise = require('bluebird');
Promise.promisifyAll(request);
I am sure I am missing something. Would really appreciate some clarification.
Interesting question. At least this super-basic example works:
const request = require('supertest');
const Bluebird = require('bluebird');
Bluebird.promisifyAll(request);
const app = require('express')();
app.get('/', (req, res) => { res.send('Hello World'); });
describe('promisify supertest', () => {
it('works', () => {
return request(app)
.get('/')
.expect(200, 'Hello World');
});
});
@thebearingedge that's actually default behavior shipped by SuperTest these days! For example, the following works:
describe('promisify supertest', () => {
it('works', () => require('supertest')('https://google.com').get('/').expect(301));
});
See ladjs/supertest#722 for the gory details—the tl;dr is that all Test
instances have a .then()
method for Promise interop. If all you want is the ability to return SuperTest instances from within a Mocha spec and have everything Just Work, you don't need this library at all (with sufficiently recent versions of Mocha and SuperTest). But if you want all the great functions that real promise objects ship with, you'll still need SuperTest as Promised:
request(app)
.get("/kittens")
.expect(201)
.toPromise()
// I'm a real promise now! You don't get .toPromise with plain ol' SuperTest.
.delay(function (res) { /* ... */ })
.then(function (res) { /* ... */ })
@nareshbhatia, to answer your original question, Bluebird's promisifyAll
is incredibly annoying with SuperTest's API. You need to make sure to promisifyAll
in exactly the right place:
var request = require('supertest')('https://google.com');
require('bluebird').promisifyAll(request.get('/'))
.expect('Content-Type', /text/)
.expectAsync(200)
.then(/*...*/)
With just Bluebird, you need a call to promisifyAll
for each test, and you need to always make your last assertion expectAsync
instead of expect
, or you won't coerce the Test
instance to a promise, and the request won't ever get sent. SuperTest as Promised hides all this complexity from you.
Oh, HA! You're right. I didn't call expectAsync
.
Duh. 😞
Well cool. I never remember how promisifyAll
works. Apparently I never use it. Thanks for your time and knowledge, @benesch
Of course! Happy to see this library getting some use. Cheers!
@thebearingedge, @benesch - thank you for your insights. This is SuperHelpful 👍. Will start tinkering with supertest-as-promised.
P.S. BTW you folks are using node 4.0.x? How has your experience been? Do you recommend switching to it?
Awesome!
I am retired from the Node ecosystem with the exception of a few JS packages I maintain, like this one. So I am not the right person to ask for Node 4.0.x advice! I will say that I find the new =>
function syntax an extremely compelling reason to upgrade.
I'm loving v4 and highly recommend it. I have been wanting the ES6 features but don't want to sacrifice test speed or add complexity to testing with a compile step. If you use nvm
you can try it out pretty painlessly. Cheers 🍻
I am retired from the Node ecosystem
Did I miss that the last time we talked? Where'd you go?
Systems programming, it seems! School is keeping me busy with a healthy smattering of C and OCaml.