【问题标题】:How do I resolve a $q.when promise in unit tests?如何解决单元测试中的 $q.when 承诺?
【发布时间】:2014-10-12 17:55:05
【问题描述】:

我正在使用$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(),我希望会触发一个摘要,并且 承诺解决。在这种情况下,我该如何解决 promise?

注意,我已经为 PhantomJS 中的 bind/apply 支持加载了 es5-shim

编辑:我尝试将 $rootScope.$apply() 移动到测试的顶部(并在 afterEach 块中),交替到 $rootScope.$digest() 并增加 Jasmine 的超时时间 (jasmine.DEFAULT_TIMEOUT_INTERVAL = 10000;)。

【问题讨论】:

  • 也许你可以试试 $rootScope.$digest();而不是 $apply() 或调用 pouchdb.info().resolve();或两者。另一种可能是http请求时间过长,你可以设置一个更高的超时时间。您还可以查看 jasmine 中的 mock (spyOn),除非您还想测试 Web 服务。
  • 移动 $rootScope.$apply();到你的测试的顶部。摘要循环将解决所有未解决的承诺。运行后,您将可以访问已解析的值。
  • @BorisCharpentier,@bengro,我试过你的建议无济于事(见编辑)。 pouchdb.info() 不包含 .resolve 属性(它是 $q 承诺)。监视pouchdb.info 显示info() 被正确调用,但不是pouchdb.info().then

标签: angularjs unit-testing promise


【解决方案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);
  });
});

【讨论】:

    猜你喜欢
    • 2023-03-27
    • 2014-03-05
    • 1970-01-01
    • 1970-01-01
    • 2013-04-25
    • 1970-01-01
    • 2018-10-30
    • 2013-02-09
    • 1970-01-01
    相关资源
    最近更新 更多