如何在Jasmine中正确测试Angular异步函数?已尝试done回调与$apply仍失败
Angular异步函数测试踩坑求助
我最近在测试一个Angular异步函数的时候彻底卡壳了,翻了好几个相关帖子试了各种方法都没成功。试过用done回调,也试过把$apply调用放在it块外面,但测试还是通不过。下面是我的测试代码和服务代码,麻烦帮忙看看哪里出问题了!
测试文件代码
describe('description', function() { var asi; var root; var res; beforeEach(module('moduloPrueba')); beforeEach(inject(function (asincronico, $rootScope) { asi = asincronico; root = $rootScope; }) ); it('uno', function(){ asi.tes().then(function(po){ res = po; }); root.$digest(); expect(res).toBe(9); }); });
服务代码
angular.module('...(完整服务代码未提供)
我试过的方法&当前困境
- 尝试使用
done回调处理异步逻辑,但没搞对姿势 - 试过把
$apply移到it块外部,依然无效 - 调用了
root.$digest()来触发Promise回调,但res还是没拿到预期值
可能的解决思路
用
done回调明确通知测试完成
异步测试里,需要明确告诉测试框架什么时候异步操作结束,避免断言在回调执行前就跑了:it('uno', function(done){ asi.tes().then(function(po){ expect(po).toBe(9); done(); // 必须调用done,否则测试会超时 }).catch(function(err) { done.fail(err); // 捕获错误,避免测试静默失败 }); root.$digest(); });直接返回Promise让测试框架自动等待
Angular的测试框架支持直接返回Promise,它会自动等待Promise完成再执行断言:it('uno', function(){ return asi.tes().then(function(po){ expect(po).toBe(9); }); });确认服务里的Promise是Angular的
$q实例
如果你的asincronico.tes()返回的是原生Promise或者其他异步库的Promise,Angular的$digest循环不会触发它的回调。这时候需要把异步操作包装在$q里,或者用$timeout替代原生setTimeout这类API。尝试用
$rootScope.$apply()替代$digest()
有时候$apply()会比$digest()更彻底地触发脏检查,确保所有异步回调都被执行:it('uno', function(){ asi.tes().then(function(po){ res = po; }); root.$apply(); expect(res).toBe(9); });
内容的提问来源于stack exchange,提问作者Ivan Paredes
相关产品推荐
相关产品推荐

