简体   繁体   中英

AngularJS : How to test a promise resolved in a callback function

I have written a function which opens an indexedDB. I'm using a promise, because I think it is the cleanest way to handle this.

  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;
      }
    };
  };

In order to test this, I have created the following test function:

  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();
    });
  });

This prints 'Success!' in the console, but the promise is never resolved.

If I move $rootScope.$apply() to the end of the onsuccess function, the promise is resolved, but only for one test. Other tests then throw an error Error: [$rootScope:inprog] $digest already in progress .

How should I resolve this promise? Is a callback function better?

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;
      }
    };
  };

Also you should use var promise = resource.finalize(); one time for all tests

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM