单元测试,等待$ http不被调用时的承诺

时间:2014-04-06 01:30:54

标签: angularjs unit-testing promise

我有一个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;

2 个答案:

答案 0 :(得分:3)

所有承诺,无论它们处于何种模式,都会在您调用$ scope时得到解决。$ digest();

答案 1 :(得分:2)

您在服务中使用promise antipattern,这就是您遇到这些问题的原因。相反,尝试这种模式:

function loadSchedules () {
  return (cachedSchedules) ? $q.when(cachedSchedules) : asyncHTTPStuffs();
}

Thanks to Benjamin Gruenbaum

这样,无论缓存状态如何,您都可以返回一个可对象的对象,而如果您知道数据已缓存,则无需调用$httpBackend.flush()