svc.test = function(foo){ if (!foo){ // return Promise.reject(new Error('foo is required')); return $q.reject(new Error('foo is required')); } else { // get data via ajax here return $q.resolve({}); } }; it.only('should error on no foo',function(){ var resolvedValue = MyServices.test(); $rootScope.$apply(); return resolvedValue.should.eventually.be.rejectedWith(TypeError,'foo is required'); });
单元测试只是超时了.我不确定我在这里做错了什么来得到正确解决的承诺.使用$q似乎是一个问题 – 当我使用本机Promise.reject()时,它工作正常.
我在这里提交了一张票,但似乎没有人回应:
https://github.com/domenic/chai-as-promised/issues/150
it('does not work',() => { $timeout.flush(); expect(myAsyncTask()).to.eventually.become('foo'); }) it('does work',() => { expect(myAsyncTask()).to.eventually.become('foo'); $timeout.flush(); })
在刷新异步任务队列之前,需要启动对异步任务的调用.
另外,不要使用$rootScope.$digest.这可能会产生其他副作用,这些副作用在您的测试中是不可取的.
$timeout.flush是你正在寻找的.
https://docs.angularjs.org/api/ngMock/service/ $超时
让您的特定测试工作:
it('should error on no foo',function(){ MyServices.test().should.eventually.be.rejectedWith(TypeError,'foo is required') $rootScope.$apply(); }); it('should pass on foo',function(){ MyServices.test('foo').should.eventually.become({}); $rootScope.$apply(); }
TL;博士
it('async test',() => { setup(); expect(); execute(); }) it('sync test',() => { setup(); execute(); expect(); })
鉴于发表的评论:
Should it be mentioned that it is unethical to downvote ‘rival’ answers on the question you’re answering?
很公平.我认为答案是误导性的,因为没有必要进行额外的设置以使得使用Angular的承诺可以在不必处理完成的回调的情况下使用它. Fwiw,我会继续尝试撤销所说的downvote,并对此有道德.
The OP has no signs of timeout in his code and doesn’t state that the task is asynchronous.
$rootScope.$digest()
has no side effects in specs when called outside of scope digest. The reason why it is not recommended in production is because it doesn’t have the safeguards that$apply
has.
$rootScope.$digest实际上与$rootScope相同.$apply(和$scope.$适用于此事). source
$timeout.flush也将刷新非基于$timeout的函数.它不是基于$timeout的功能所独有的.
Plunker展示它如何工作™:
plunker