NativeScript-Karma含Promise的单元测试未执行问题求助
我之前在NativeScript + Angular的测试环境里也遇到过类似的坑——明明Promise是立即resolve的,但测试里的then回调就是死活不触发。结合你的代码来看,问题大概率出在测试框架对异步任务的处理逻辑上,尤其是NativeScript的nsTestBedBeforeEach和常规Angular测试床的细微差异。
下面给你几个可行的解决方案:
方案1:用async/await替代done()(最推荐)
async/await语法本身就是为简化异步代码而生的,而且在Angular测试里能被Karma/Jasmine完美识别,自动等待Promise完成再结束测试。修改你的测试用例如下:
it('getHttpHeader - token data exists and it is valid', async () => { const result = await service.getHttpHeader(); console.log('2'); // 现在会正常执行 expect(result).not.toBeNull(); expect(result).toBe('a'); // 可以再加个具体值的断言更严谨 });
这种方式不需要手动调用done(),代码简洁直观,还避免了回调嵌套的问题。
方案2:用fakeAsync + tick()手动触发微任务
如果偏好回调式写法,可以借助Angular测试工具里的fakeAsync和tick(),强制清空微任务队列,让Promise的回调执行:
import { fakeAsync, tick } from '@angular/core/testing'; // ... it('getHttpHeader - token data exists and it is valid', fakeAsync(() => { let response: string | null = null; service.getHttpHeader().then(res => { response = res; console.log('2'); }); tick(); // 手动触发所有待执行的微任务 expect(response).not.toBeNull(); expect(response).toBe('a'); }));
tick()会模拟时间流逝,让所有pending的微任务(比如Promise的回调)都执行完毕,这样断言就能拿到正确的结果了。
为什么原来的done()不生效?
你的原始代码里,done()写在then回调里,但NativeScript的测试环境中,Karma可能没有自动检测到Promise的微任务完成,导致测试进程在then回调执行前就已经结束了(虽然你看到了1和3的日志,但测试已经跑完退出了)。而上面两种方案都是明确告诉测试框架:必须等异步任务完成再结束测试。
另外也可以检查下nsTestBedBeforeEach的配置是否正确,确保测试模块已经正确初始化了SsoAuthenticationService,不过从你的代码看这部分应该是没问题的。
内容的提问来源于stack exchange,提问作者user1261710

