Angular测试中调用api.send后formDef与optionsDict为undefined如何解决
问题原因
- 异步逻辑未等待就执行断言
api.send返回的是Promise实例,then内的回调属于微任务,会在当前所有同步代码执行完毕后才运行。你调用component.ngOnInit()后直接执行打印和断言操作,此时then回调还没触发,formDef和optionsDict都未完成赋值,自然返回undefined、断言失败。 - 测试代码res变量存在语法错误
你定义res的代码末尾缺少闭合的方括号,正确的两层数组结构需要]]收尾,你的代码只写了一个],语法错误会导致res初始化失败,即便等待异步执行也会出现异常。
修复方案
- 先修正res的语法错误,补全闭合符号:
let res = [[{ field_id: 66, field_key: "[[agents]]", field_label: "Agents", field_type: "select2", options: [{id: 1, name: 'Camilo'}, {id: 2, name: 'Monica'}] }]];
- 调整测试代码处理异步逻辑,推荐用Angular测试工具自带的
fakeAsync+tick方案:
import { fakeAsync, tick } from '@angular/core/testing'; it('should correctly init formDef and optionsDict', fakeAsync(() => { const res = [[{ field_id: 66, field_key: "[[agents]]", field_label: "Agents", field_type: "select2", options: [{id: 1, name: 'Camilo'}, {id: 2, name: 'Monica'}] }]]; const spy1 = spyOn(api, 'send').and.returnValue(Promise.resolve(res)); component.ngOnInit(); // tick会触发所有待执行的微任务,等待Promise回调执行完成 tick(); console.log(component.optionsDict); expect(spy1).toHaveBeenCalled(); expect(component.formDef).toEqual(res); }));
也可以用async/await写法实现同样效果:
it('should correctly init formDef and optionsDict', async () => { const res = [[{ field_id: 66, field_key: "[[agents]]", field_label: "Agents", field_type: "select2", options: [{id: 1, name: 'Camilo'}, {id: 2, name: 'Monica'}] }]]; const spy1 = spyOn(api, 'send').and.returnValue(Promise.resolve(res)); component.ngOnInit(); // 等待微任务队列清空 await Promise.resolve(); console.log(component.optionsDict); expect(spy1).toHaveBeenCalled(); expect(component.formDef).toEqual(res); });
内容的提问来源于stack exchange,提问作者David Angarita
相关产品推荐
相关产品推荐

