如何解决在AngularJS,Jasmine 2.0中没有$范围强制摘要的承诺?
看来,承诺不会在Angular / Jasminetesting中解决,除非你强制$scope.$digest()
。 这是愚蠢的国际海事组织,但罚款,我有适用的工作(控制器)。
我现在的情况是我有一个服务,可以不在乎应用程序中的任何范围,它只是从服务器返回一些数据,但承诺似乎没有解决。
app.service('myService', function($q) { return { getSomething: function() { var deferred = $q.defer(); deferred.resolve('test'); return deferred.promise; } } });
describe('Method: getSomething', function() { // In this case the expect()s are never executed it('should get something', function(done) { var promise = myService.getSomething(); promise.then(function(resp) { expect(resp).toBe('test'); expect(1).toEqual(2); }); done(); }); // This throws an error because done() is never called. // Error: Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL. it('should get something', function(done) { var promise = myService.getSomething(); promise.then(function(resp) { expect(resp).toBe('test'); expect(1).toEqual(2); done(); }); }); });
什么是testing这个function的正确方法?
编辑:解决scheme供参考。 显然,即使服务没有使用它,也不得不注入并消化$ rootScope。
it('should get something', function($rootScope, done) { var promise = myService.getSomething(); promise.then(function(resp) { expect(resp).toBe('test'); }); $rootScope.$digest(); done(); });
您需要在您的testing中注入$rootScope
并触发$digest
。
总是有$ rootScope,使用它
inject(function($rootScope){ myRootScope=$rootScope; }) .... myRootScope.$digest();
所以我整个下午都在苦苦挣扎。 读完这篇文章之后,我也觉得答案有点不一样,结果就是这样。 上面的答案都没有给出清楚的解释,说明在哪里以及为什么要使用$rootScope.$digest
。 所以,这就是我想出来的。
首先为什么? 无论何时从非angular度事件或callback响应,都需要使用$rootScope.$digest
。 这将包括纯粹的DOM事件,jQuery事件和其他第三方Promise库,而不是$q
,它是angular的一部分。
其次呢? 在你的代码中,不是你的testing。 没有必要在您的testing中注入$rootScope
,它只在您的实际angular度服务中需要。 这就是所有上面都没有明确答案的地方,他们显示$rootScope.$digest
是从testing中调用的。
我希望这有助于下一个长期存在同样问题的人。
更新
我昨天把这个post删掉了,当时投了票。 今天我仍然有这个问题试图使用上面的恩惠提供的答案。 所以,我以牺牲口碑为代价来等待我的回答,因此,我正在放弃它。
这是你在非angular度的事件处理程序中所需要的,而且你正在使用$ q并试图用Jasmine进行testing。
something.on('ready', function(err) { $rootScope.$apply(function(){deferred.resolve()}); });
请注意,在某些情况下可能需要将其封装在$ timeout中。
something.on('ready', function(err) { $timeout(function(){ $rootScope.$apply(function(){deferred.resolve()}); }); });
再一个注意。 在原来的问题示例中,您在错误的时间
done
调用。 你需要在then
方法(或者catch
或者finally
)里面调用promise的内容,然后解决。 您在promiseparsing之前调用它,导致it
子句终止。
从angular度文件。
https://docs.angularjs.org/api/ng/service/ $ q
it('should simulate promise', inject(function($q, $rootScope) { var deferred = $q.defer(); var promise = deferred.promise; var resolvedValue; promise.then(function(value) { resolvedValue = value; }); expect(resolvedValue).toBeUndefined(); // Simulate resolving of promise deferred.resolve(123); // Note that the 'then' function does not get called synchronously. // This is because we want the promise API to always be async, whether or not // it got called synchronously or asynchronously. expect(resolvedValue).toBeUndefined(); // Propagate promise resolution to 'then' functions using $apply(). $rootScope.$apply(); expect(resolvedValue).toEqual(123); }));