AngularJS:如何测试在回调函数中解决的promise

时间:2014-12-08 14:41:57

标签: javascript angularjs jasmine angular-promise

我编写了一个打开indexedDB的函数。我使用了一个承诺,因为我认为这是处理这个问题最干净的方法。

  this.$get = function($q, $rootScope, $window) {
    return {
      finalize: function() {
        var deferred = $q.defer();
        var dbRequest = $window.indexedDB.open(dbName, dbVersion);
        dbRequest.onupgradeneeded = function(event) {
          // XXX do something here.
        };
        dbRequest.onsuccess = function(event) {
          db = event.target.result;
          console.log('Success!');
          deferred.resolve(event);
        };
        dbRequest.onerror = deferred.reject;
        return deferred.promise;
      }
    };
  };

为了测试这个,我创建了以下测试函数:

  describe('finalize', function() {
    it('should initialize the database', function(done) {
      var promise = resource.finalize();
      promise.then(function() {
        console.log('resolved');
        var transaction = resource.db.transaction(['Component']);
        expect(transaction).toBeDefined();
        done();
      });
      $rootScope.$apply();
    });
  });

这会在控制台中打印'Success!',但承诺永远不会解决。

如果我将$rootScope.$apply()移动到onsuccess函数的末尾,则解析承诺,但仅针对一个测试。然后其他测试会抛出错误Error: [$rootScope:inprog] $digest already in progress

我该如何解决这个承诺?回调函数更好吗?

1 个答案:

答案 0 :(得分:2)

this.$get = function($q, $rootScope, $window) {
    return {
      finalize: function() {
        var deferred = $q.defer();
        var dbRequest = $window.indexedDB.open(dbName, dbVersion);
        dbRequest.onupgradeneeded = function(event) {
          // XXX do something here.
        };
        dbRequest.onsuccess = function(event) {
          db = event.target.result;
          console.log('Success!');
          $rootScope.$apply(function () {
             deferred.resolve(event);
           });              
        };
        dbRequest.onerror = function (error) {
            $rootScope.$apply(function () {
                deferred.reject(error);
             });
         } 
        return deferred.promise;
      }
    };
  };

你也应该使用var promise = resource.finalize();一次性进行所有测试