Angular NgbModal单元测试报Cannot set properties of undefined错误如何修复
你遇到的TypeError: Cannot set properties of undefined (setting 'object')错误有两个核心原因:
- 你定义的
MockNgbModalRef仅声明了componentInstance的类型,没有做实际的初始化赋值,默认值就是undefined,当业务代码尝试给modalRef.componentInstance.object赋值时就会抛出错误。 - 你在spy
ngbModal.open方法时,返回的是MockNgbModalRef类本身,而不是类的实例,导致实际拿到的modalRef不是可用的实例对象。
修复步骤
1. 修正MockNgbModalRef的定义
给componentInstance初始化实际的对象,避免undefined:
export class MockNgbModalRef { // 这里要直接赋值初始化对象,而不是仅声明类型 componentInstance = { object: undefined, button: undefined }; result: Promise<any> = new Promise((resolve, reject) => resolve('accept')); }
2. 修正spy的返回值
将ngbModal.open的spy返回值改为你已经实例化的mockModalRef对象,而不是类本身:
it('Should remove the report', () => { let report = { id:1, name: 'Prueba', date: "2021-09-23", contents: ['contenido de prueba'] } // 这里返回mockModalRef实例,不要返回MockNgbModalRef类 let spy1 = spyOn(ngbModal, 'open').and.returnValue(mockModalRef as any); component.remove(report); expect(spy1).toHaveBeenCalled(); expect(spy1).toHaveBeenCalledTimes(1); expect(spy1).toHaveBeenCalledWith(ConfirmModalComponent, {scrollable: true, windowClass: 'myCustomModalClass'}); });
可选:测试result回调逻辑
如果需要测试modalRef.result.then内的逻辑(比如删除报表、调用api的分支),可以用fakeAsync处理异步逻辑:
it('Should remove the report when modal returns accept', fakeAsync(() => { let report = { id:1, name: 'Prueba', date: "2021-09-23", contents: [] }; component.reports = [report]; const apiSpy = spyOn(component.api, 'send').and.callThrough(); spyOn(ngbModal, 'open').and.returnValue(mockModalRef as any); component.remove(report); tick(); // 触发Promise回调执行 expect(component.reports.length).toBe(0); expect(apiSpy).toHaveBeenCalledWith('Reports', 'removeReport', { report: report }); }));
内容的提问来源于stack exchange,提问作者David Angarita
相关产品推荐
相关产品推荐

