Reputation: 18107
I have a unittest where a service returns a promise. Sometimes that service might make a $http request, sometimes it won't (It implements a cache of sorts). In either case, it resolves the promise, but only in $httpBackend.flush() does it actually get around to making the callbacks. How can I cause the promises that are resolved to actually call the functions in the .then()
like flush() does.
This one works just fine
resolved = jasmine.createSpy();
rejected = jasmine.createSpy();
employeeEventService.loadSchedules()
.then(resolved, rejected);
$httpBackend.flush(); // This causes the promise to resolve/reject
expect(resolved).toHaveBeenCalled();
expect(rejected).not.toHaveBeenCalled();
This one doesn't work because I can't call flush() (since the service never called $http)
resolved = jasmine.createSpy();
rejected = jasmine.createSpy();
employeeEventService.loadSchedules()
.then(resolved, rejected);
//$httpBackend.flush(); // Can't call this because this call is "cached"
expect(resolved).toHaveBeenCalled();
expect(rejected).not.toHaveBeenCalled();
Service code:
if(loaded.startOn <= params.startOn && loaded.endOn >= params.endOn
&& new Date() - lastFetch < 60000) {
deferred.resolve(loaded.schedules);
} else {
service.loading +=1;
config = {params: params, timeout:30*1000};
$http.get('/api/employee-schedules/', config)
.then(function(response) {
...
process the json response
...
deferred.resolve(loaded.schedules);
}, function(reason, status) {
$log.error("Failed to get schedules", reason, status);
deferred.reject(reason, status);
})
.finally(function() {
service.loading -=1;
});
}
return deferred.promise;
Upvotes: 2
Views: 2698
Reputation: 6620
All promises, regardless of what pattern they are in, are resolved when you call $scope.$digest();
Upvotes: 3
Reputation: 39532
You're using a promise antipattern in your service, which is why you're encountering these issues. Instead, try this pattern:
function loadSchedules () {
return (cachedSchedules) ? $q.when(cachedSchedules) : asyncHTTPStuffs();
}
(Thanks to Benjamin Gruenbaum)
This way, you can return a thenable object, regardless of cache status, while not needing to call $httpBackend.flush()
if you know the data is cached.
Upvotes: 2