Angular单元测试报Cannot read properties of undefined (reading 'find')求助
Angular单元测试
Cannot read properties of undefined (reading 'find')报错解决方案 问题根因
报错的核心原因是测试运行时,业务代码中使用的this['stpCodeDtl'].Columns未完成初始化,值为undefined,调用find方法自然触发异常。Angular单元测试默认不会自动初始化自定义子组件、第三方组件的实例属性,也不会自动生成表格列配置这类业务数据,需要测试代码手动模拟赋值。
修复步骤
1. 测试前置初始化模拟数据
在测试文件的beforeEach钩子中,提前给stpCodeDtl和它的Columns属性模拟符合业务结构的初始值,同时对要断言的afterNew、afterModify方法做监听:
beforeEach(() => { fixture = TestBed.createComponent(你的组件类名); component = fixture.componentInstance; // 新增以下模拟代码 spyOn(component, 'afterNew').and.callThrough(); spyOn(component, 'afterModify').and.callThrough(); component['stpCodeDtl'] = { Columns: [ { field: 'codeNo', visible: true }, { field: 'codeTyp', visible: true }, { field: 'codeTypNm', visible: true } // 其他需要用到的列配置可以继续补充 ] }; fixture.detectChanges(); });
2. 修正测试用例逻辑
你的原测试用例断言逻辑有误,业务代码是将codeNo列的visible属性设为false,不是删除该列,修改后测试用例如下:
it('should trigger afterNew and set codeNo column invisible', () => { component.scrMenusEvents(quickAction.afterNewQuick); // 断言afterNew调用参数正确 expect(component.afterNew).toHaveBeenCalledWith({ dimmedControls: ['codeTyp', 'codeTypNm'] }); // 断言codeNo列的visible属性被修改为false const targetColumn = component['stpCodeDtl'].Columns.find(item => item.field === 'codeNo'); expect(targetColumn.visible).toBeFalse(); }); it('should trigger afterModify and set codeNo column invisible', () => { component.scrMenusEvents(quickAction.afterModifyQuick); // 断言afterModify调用参数正确 expect(component.afterModify).toHaveBeenCalledWith({ dimmedControls: ['codeTyp', 'codeTypNm'] }); // 断言codeNo列的visible属性被修改为false const targetColumn = component['stpCodeDtl'].Columns.find(item => item.field === 'codeNo'); expect(targetColumn.visible).toBeFalse(); });
同类问题通用解决思路
你提到的find/forEach方法、订阅逻辑测试经常报错,统一遵循以下规则即可解决:
- 所有业务代码中访问的对象、数组属性,只要不是组件自身初始化赋值的,都要在测试运行前手动模拟对应的结构和初始值,数组即使没有数据也要初始化为
[],不能为undefined/null - 订阅类逻辑不要调用真实接口,用RxJS的
of()方法模拟Observable返回值,提前对依赖的服务方法做spy - 访问深层嵌套属性前,确保每一层的父级对象都已经完成初始化赋值
内容的提问来源于stack exchange,提问作者Omar Khaled
相关产品推荐
相关产品推荐

