Reputation: 11
I'm trying to test what the following method returns in it's promise (functionToTest
and asyncGet
are both methods defined in an angularJS service):
var functionToTest = function (param) {
var deferred = $q.defer();
asyncGet(param).then(function (result) {
//business login involving result
if (something)
return deferred.resolve(true);
else
return deferred.resolve(false);
});
return deferred.promise;
}
The unit test looks like this:
it ('should return true', function (done) {
var asyncGetResult = {};
spyOn(asyncGet).and.returnValue($q.resolve(asyncGetResult));
var param = {};
functionToTest(param).then(function (result) {
expect(result).toBe(true);
done();
});
$scope.$apply();
});
When running the test I am getting a timeout error:
Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.
I tried putting a console.log()
right after the expect()
but it does not print anything, so it seems like the callback for the functionToTest(param).then()
is never executed.
Any help would be appreciated.
Upvotes: 0
Views: 375
Reputation: 48968
Remove the $q.deferred anti-pattern:
var functionToTest = function (param) {
̶v̶a̶r̶ ̶d̶e̶f̶e̶r̶r̶e̶d̶ ̶=̶ ̶$̶q̶.̶d̶e̶f̶e̶r̶(̶)̶;̶
return asyncGet(param).then(function (result) {
//business login involving result
if (something)
return true;
else
return false;
});
̶r̶e̶t̶u̶r̶n̶ ̶d̶e̶f̶e̶r̶r̶e̶d̶.̶p̶r̶o̶m̶i̶s̶e̶;̶
}
Also provide an error handler:
functionToTest(param).then(function (result) {
expect(result).toBe(true);
done();
}).catch(function(err) {
console.log(err);
done();
});
Deferred anti-patterns can hang if the code is written erroneously. Avoid the anti-pattern to prevent this problem.
Include a .catch
handler to see any errors.
Upvotes: 0