如何在单元测试中解决$ q.when的承诺?

时间:2014-10-12 17:55:05

标签: angularjs unit-testing promise

我正在使用$q.when转换第三方承诺(由PouchDB返回的承诺) 进入Angular的承诺。

假设:

'use strict';
angular.module('test', [])
  .service('pouchdb', function($q, $window) {
    var db = new $window.PouchDB('test');
    this.info = function() {
      return $q.when(db.info.apply(db, arguments));
    };
  })
  .controller('test', function($scope, pouchdb) {
    pouchdb.info()
      .then(function(info) {
        $scope.result = info;
      })
      .catch(function(error) {
        $scope.result = error;
      });
  });

...在浏览器中,系统会返回info并正确更新$scope。然而, 给出以下单元测试(Jasmine 2.x):

describe('Q when tests', function() {
  beforeEach(module('test'));

  var $rootScope, pouchdb;
  beforeEach(inject(function(_$rootScope_, pouchdb) {
    $rootScope = _$rootScope_;
    pouchdb = pouchdb;
  }));

  it('should resolve a promise', function(done) {
    pouchdb.info()
      .then(function(info) {
        expect(info).toBeDefined();
      })
      .finally(done);
    $rootScope.$apply();
  });
});

... info永远不会被解决,Jasmine(通过Karma& PhantomJS)抛出:

Error: Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.

通过调用$rootScope.$apply(),我希望能够触发一个摘要 承诺得到解决。在这种情况下如何解决承诺?

注意,我已在PhantomJS中加载es5-shim / bind支持apply

修改:我已尝试将$rootScope.$apply()移至测试顶部(并在afterEach区块中),交替显示$rootScope.$digest()并增加Jasmine的超时时间(jasmine.DEFAULT_TIMEOUT_INTERVAL = 10000; )。

1 个答案:

答案 0 :(得分:1)

在不知不觉中,我通过手动注入ng来解决了这个问题:

describe('Working Q when tests', function() {
  var pouchdb;
  beforeEach(function() {
    var $injector = angular.injector(['ng', 'test']);
    var pouchDB = $injector.get('pouchdb');
    pouchdb = pouchDB('db');
  });

  it('should resolve a promise', function(done) {
    pouchdb.info()
      .then(function(info) {
        expect(info).toBeDefined();
      })
      .finally(done);
  });
});