I've got a service, PageService, that I test like this (simplified)...
var database = require("../database/database");
var PageService = require("./pageService");
describe("PageService", function () {
var pageService = {};
before(function (done) {
pageService = new PageService(database);
}
it("can get all Pages", function (done) {
pageService.getAll(function (err, pages) {
if (err) return done(err);
pages.should.be.instanceOf(Array);
pages.length.should.be.greaterThan(1);
done();
});
});
I've struggled to use bluebird to promisify all the methods hanging off of PageService (getAll, getById, create, update, delete, etc). I've looked at several discussions on the topic, but most seem to concern trying to get constructors to return a promise. I just want to promisify all the functions hanging off the class I create via a constructor. It's the pageService = new PageService(database); that I can't get past for promisification.
PageService is just using a basic constructor pattern - e.g.
self.getAll = function(next) {
self.collection.find({}, function(err, docs) {
if (err) return next(err);
next(null, docs);
});
};
If someone could show me the proper way to easily promisify all the functions hanging off the object returned from the constructor, I'd appreciate it. I'm also open to the fact that I may be doing this the wrong way. I'm pretty new to promises in general and welcome guidance.
I got the functions promisified by doing the following...
pageService = new PageService(database);
Promise.promisifyAll(pageService);
... but that seems like a bad practice to run through promisification every time I new up an instance of the service. I'd like a way to promisify once and only once. I recognize that manually returning promises in the service might be the solution, but was hoping for something more elegant via bluebird magic.
PageService module:
function PageService(collection) {
this.collection = collection;
}
PageService.prototype.getAll = function(next) {
this.collection.find({}, function(err, docs) {
if (err) return next(err);
next(null, docs);
});
};
module.exports = PageService;
test module
var should = require("should");
var Promise = require("bluebird");
var database = { // mockup
find: function (options, next) {
next(null, ['the', 'list', 'of', 'docs']);
}
};
var PageService = require("./PageService");
Promise.promisifyAll(PageService.prototype);
describe("PageService", function () {
var pageService;
before(function () {
pageService = new PageService(database);
});
it("can get all pages", function () {
return pageService.getAllAsync()
.then(function (pages) {
pages.should.be.instanceOf(Array);
pages.length.should.be.greaterThan(1);
});
});
});
You shouldn't be concerned about promisification every time. All it does is just wrapping your callbacks in appropriate promise code. There is no performance penalty to be concerned about and it's a perfectly acceptable solution.
Also there is no other way to do it. It all comes down to two solutions: using Bluebird
promisification
or manually rewriting your service to work with promises
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With