我尝试测试一个使用嵌套promises的函数(让我们假设这个函数不能改变)。为了处理这些承诺,我必须至少调用$rootScope.$digest()
两次。我提出了这个有效的解决方案,每隔10毫秒调用$digest()
。
// Set some async data to scope.key
// Note: This function is just for demonstration purposes.
// The real code makes async calls to localForage.
function serviceCall(scope, key) {
var d1 = $q.defer(), d2 = $q.defer();
setTimeout(function () {
d1.resolve('d1');
});
d1.promise.then(function (data) {
setTimeout(function () {
d2.resolve(data + ' - d2');
}, 100); // simulate longer async call
});
d2.promise.then(function (data) {
scope[key] = data;
});
}
it('nested promises service', function (done) {
var interval = setInterval(function () {
$rootScope.$digest();
}, 10),
myKey = 'myKey',
scope = {};
serviceCall(scope, myKey);
setTimeout(function () {
expect(scope[myKey]).toEqual('d1 - d2');
window.clearInterval(interval);
done();
}, 120); // What is the right timeout?
});
问题是估计消化足够时间以解决所有承诺所需的超时持续时间。如果服务对例如服务进行真正的异步调用,则会变得更加复杂。 localStorage的。
还有另一种解决方法吗?有没有办法获得所有剩余的承诺?
答案 0 :(得分:2)
您应该使用jasmine spies来模拟/存根任何外部服务调用,以便您可以控制服务何时解析/拒绝。您的服务应该备份其内部功能的测试。
请注意,这个例子并不完美,但为了清楚起见缩写。
var service = jasmine.createSpyObj('service', ['call']);
var defServiceCall;
var $scope;
beforeEach(function () {
module('myModule', function ($provide) {
// NOTE: Replaces the service definition with mock.
$provide.value('service', service);
});
inject(function($q, $rootScope) {
$scope = $rootScope.$new();
defServiceCall = $q.defer();
service.call.and.returnValue(defServiceCall.promise);
});
});
describe('When resolved', function () {
beforeEach(function () {
myFunctionCall(); // Sets myVar on the scope
defServiceCall.resolve('data');
$scope.$digest(); // NOTE: Must digest for promise to update
});
it('should do something awesome when resolved', function () {
expect($scope.myVar).toEqual('data');
});
});