如何解决在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); })); 
Interesting Posts