Reputation: 13336
I have a method in my project that receives an array of promise returning methods. When the first one is finished it moves to the next one and so forth. I am having a hard time figuring how to unit test this method.
fireAllBatches: function (batchQueue, resolve, reject) {
if (batchQueue.length) {
var batch = batchQueue.pop();
// this returns a promise
googleCalendarService.fireBatch(batch)
.then(function (results) {
// when done fires the next one
this.fireAllBatches(batchQueue, resolve, reject);
}.bind(this)).catch(reject);
} else {
console.log('resolving firing of batches.');
resolve();
}
}
This is the test:
it('fireAllBatches should call fireBatch as many times as the number of the batches', function () {
spyOn(mockGoogleCalendarService, "fireBatch").and.returnValue(q.when({}));
datalayerObject.fireAllBatches([1, 2, 3, 4, 5, 6]);
expect(mockGoogleCalendarService.fireBatch).toHaveBeenCalled();
expect(mockGoogleCalendarService.fireBatch.calls.count()).toBe(6);
});
Update
After investigating and reading this answer. I was able to transform the recursive method to this:
fireAllBatches: function (batchQueue, resolve, reject) {
var methodArray = _.map(batchQueue, function (batch) {
return function () {
console.log('firing batch');
return googleCalendarService.fireBatch(batch)
}
});
var resolvedPromise = $q.when(true);
methodArray.reduce(function(cur, next) {
return cur.then(next);
}, resolvedPromise).then(resolve).catch(reject);
}
However, I am not sure whether it will catch errors correctly.
Upvotes: 0
Views: 662
Reputation: 38161
I would mock or stub out the googleCalendarService.fireBatch()
function, so you can verify what it was called with, and then you can just use a spy for the resolve and reject parameters.
Here is what I would test:
batchQueue
is null/undefined.resolve
immediately if batchQueue
is emptygoogleCalendarService.fireBatch
stub once with the first batch, and then call resolve if you pass in a queue with one batch.googleCalendarService.fireBatch
stub twice and the resolve
spy once for a queue of 2 batches.googleCalendarService.fireBatch
function throws an error that the reject
spy gets called.You may think of additional tests as well.
Upvotes: 1
Reputation: 6693
This isn't specifically an answer with regards to unit testing. However, if you're working in ES6, you could do something along these lines to avoid the recursion, and it might simplify your testing:
batchQueue.reduce( (chain,batch) => {
return chain.then(googleCalendarService.fireBatch(batch))
}, Promise.resolve(null)).then(resolve).catch(reject);
Upvotes: 1