【发布时间】: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