In unit testing Loopback it is necessary to use callbacks with the upsert methods. So for example ... instead of writing something along the lines of this:
before(function () {
Student = server.models.Student
Course = server.models.Course
Course.upsert({id: 1, key: 'A', department: 'Original department'})
Student.upsert({id: 1, points: 5000})
})
it is necessary to ensure that callbacks are used with the upsert. Since I have a lot of models I am initializing below I use async:
before(function (done) {
Student = server.models.Student
Course = server.models.Course
async.waterfall([
function (callback) {
Course.upsert({id: 1, key: 'A', department: 'Original department'}, callback)
},
function (f, callback) {
Student.upsert({id: 1, points: 5000}, callback)
},
],
function (err, results) {
done(err)
})
})
Instead of async, how would the code above be changed to use Promises?
My thought is that with promises, I would be able to write some code that looks like this:
before(function (done) {
Student = server.models.Student
Course = server.models.Course
Course.upsert({id: 1, key: 'A', department: 'Original department'})
.then(Student.upsert({id: 1, points: 5000})
.then(function(err) { done(err) }
})
but I have been unsuccessful tying into promises.
EDIT from answers below ...
before(function (done) {
Course = server.models.Course
Course.upsertWithPromise = Promise.promisify(Course.upsert)
Course.upsertWithPromise({id: 1, key: 'A', department: 'Original department'})
.then(done)
}
it.only('Course upsert', function (done) {
Course.findById(1, function (err, course) {
expect(course.id).to.equal(1)
expect(course.department).to.equal('Original department')
done()
})
})
There are two possible solutions. First is manual promisification. Your functions will look like this:
server.models.Student.upsert = function(data) { // Note NO CALLBACK
return new Promise(function(resolve, reject) {
// Here can do all async staff and when done sucessfully call:
resolve(result);
// OR on error call:
reject(err);
});
}
Second solution will be use library for the same purpose.
Then your code from your example should work fine.