如何测试带try/catch的Promise的reject分支以实现100%测试覆盖率
问题描述
我遇到了无法测试Promise reject场景的问题,现有如下resolve方法,测试覆盖率仅为92%,报错提示catch块中的reject(e)未被覆盖,我需要实现该方法100%的测试覆盖率:
public resolve(): Promise<{ [key: string]: boolean }> { return new Promise<{ [key: string]: boolean }>(async (resolve, reject) => { try { for await (const setting of settings) { // 作用类似哈希表的对象存储 this.store.set(setting.key, setting.value); } resolve(); } catch (e) { reject(e); } }); }
调试过程
我首先需要构造Mock来触发catch语句执行,但TestBed.overrideProvider对我不生效,因此我采用如下方式初始化测试模块:
it('should return a rejected promise', async() => { TestBed.resetTestingModule(); TestBed.configureTestingModule({ // 插入新的Mock提供者来触发catch逻辑 ... });
之后搭配@Apoorva Chikara给出的方案成功解决了问题,如果有更简便的实现方式欢迎告知。
最终可运行测试代码
it('should return a rejected promise', async() => { TestBed.resetTestingModule(); TestBed.configureTestingModule({ providers: [ { provide: ObjectStore, useValue: new ObjectStore('test'), }, { // 将客户端设为无效值来触发catch抛出错误 // 也可以写一个Mock类主动抛出错误实现同样效果 // 这里的settings对应Azure的listConfigurationSettings返回值 provide: AppConfigurationClient, useValue: {}, } ] }); service = TestBed.inject(FeatureFlagResolver); store = TestBed.inject(ObjectStore); const rejection = async () => { await service.resolve().catch(); } await expect(rejection()).rejects.toThrow(); });
业务背景补充
- 代码中的
settings来自微软Azure的listConfigurationSettings接口,用于读取Azure配置项,实现Angular站点的功能开关动态配置 - 实际使用逻辑:如需在Angular站点启用某个功能,只需到Azure门户修改对应app-setting值(例如将
chatbot设为on),页面即可自动展示聊天机器人,目前该能力仅用于功能开关切换场景
内容的提问来源于stack exchange,提问作者Zeo
相关产品推荐
相关产品推荐

