我有一个unittest,服务返回一个promise。有时该服务可能会生成$ http请求,有时它不会(它实现了各种缓存)。在任何一种情况下,它都解决了这个承诺,但只有在$ httpBackend.flush()中才能实现回调。如何解决实际调用.then()
中的函数(如flush())所解决的promise。
这个工作得很好
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();
这个不起作用,因为我无法调用flush()(因为该服务从未调用$ 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();
服务代码:
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;
答案 0 :(得分:3)
所有承诺,无论它们处于何种模式,都会在您调用$ scope时得到解决。$ digest();
答案 1 :(得分:2)
您在服务中使用promise antipattern,这就是您遇到这些问题的原因。相反,尝试这种模式:
function loadSchedules () {
return (cachedSchedules) ? $q.when(cachedSchedules) : asyncHTTPStuffs();
}
(Thanks to Benjamin Gruenbaum)
这样,无论缓存状态如何,您都可以返回一个可对象的对象,而如果您知道数据已缓存,则无需调用$httpBackend.flush()
。