Angular单元测试:spyOn返回Promise的方法时用例失败如何解决
失败原因
测试用例执行失败的核心原因是没有等待异步逻辑执行完成就触发了断言:
nextEmployee是async方法,内部的Promise属于微任务,不会在方法调用的同步执行阶段完成- 现有测试代码调用
component.nextEmployee(10)后,会立刻执行expect断言,此时CheckLastEmployee返回的Promise还没resolve,isLast还没被赋值为true,Submit()方法根本还没触发,断言自然失败。
正确测试写法
Angular单元测试处理Promise类异步逻辑,推荐两种常用写法:
写法1:async + whenStable
依赖Angular测试工具自带的异步等待能力,等待所有未完成的异步任务执行完毕后再做断言:
it('Is Last Employee-submit', async(() => { spyOn(component, 'CheckLastEmployee').and.returnValue(Promise.resolve(true)); spyOn(component, 'Submit'); component.nextEmployee(10); fixture.whenStable().then(() => { expect(component.Submit).toHaveBeenCalled(); }); }));
写法2:fakeAsync + tick
用虚拟时间清空任务队列,不需要等待真实异步延迟,执行速度更快、更可控:
it('Is Last Employee-submit', fakeAsync(() => { spyOn(component, 'CheckLastEmployee').and.returnValue(Promise.resolve(true)); spyOn(component, 'Submit'); component.nextEmployee(10); // 执行所有待处理的微任务 tick(); // 也可以用flush()替代tick(),会自动清空所有排队的微任务、宏任务 expect(component.Submit).toHaveBeenCalled(); }));
额外优化提示
当前业务代码里的Promise写法存在冗余,await this.CheckLastEmployee(empId).then(x=>{isLast=x})可以直接简化为isLast = await this.CheckLastEmployee(empId),二者逻辑完全等价,可读性更高。
内容的提问来源于stack exchange,提问作者PRI
相关产品推荐
相关产品推荐

