Angular测试报错:Cannot read properties of undefined (reading 'userRoleDOList')求助
问题场景
测试Angular的AppLayoutComponent时出现如下报错:
TypeError: Cannot read properties of undefined (reading 'userRoleDOList') at AppLayoutComponent.getMenu (http://localhost:9876/_karma_webpack_/webpack:/src/app/BaseFramework/base-ui/app-layout/app-layout.component.ts:405:52) at AppLayoutComponent.ngOnInit (http://localhost:9876/_karma_webpack_/webpack:/src/app/BaseFramework/base-ui/app-layout/app-layout.component.ts:381:12)
原因是组件ngOnInit会调用getMenu方法,该方法依赖userInfoService.getUserInfo()返回对象中的userRoleDOList属性,但测试中未正确mock该依赖。需求是仅测试ngOnInit以外的其他函数,无需执行getMenu方法。
解决方案
方案1:让ngOnInit跳过getMenu执行
组件ngOnInit中通过environment['hardcodedMenu']判断是否调用getMenu,只需在测试中修改该环境变量,让代码走硬编码菜单分支,避免执行getMenu:
- 先导入环境变量(如果未导入):
import { environment } from 'src/environments/environment';
- 在测试的
beforeEach中设置环境变量,并移除主动调用的component.getMenu():
beforeEach(() => { // 设置环境变量,让ngOnInit走hardcodedMenu分支 environment['hardcodedMenu'] = true; fixture = TestBed.createComponent(AppLayoutComponent); component = fixture.componentInstance; fixture.detectChanges(); // 移除主动调用getMenu的代码:component.getMenu() });
方案2:伪造依赖让getMenu执行不报错(若需保留ngOnInit完整执行)
如果必须执行ngOnInit但不想触发getMenu的报错,可mock相关依赖的返回值:
- 在创建
mockUserInfoService时,让getUserInfo返回包含userRoleDOList的对象:
mockUserInfoService = jasmine.createSpyObj('UserInfoService', ['getUserInfo','setUserInfo']); // 返回包含userRoleDOList的模拟用户信息 mockUserInfoService.getUserInfo.and.returnValue({ userRoleDOList: [{ roleId: 'mock-role-id' }] });
- 同时mock
CommonUtilty的isArrayIterable方法返回true(或根据逻辑返回false):
mockCommonUtilty= jasmine.createSpyObj('CommonUtility', ['getAppMetadata','isArrayIterable']); mockCommonUtilty.isArrayIterable.and.returnValue(true);
- 同样移除测试
beforeEach中主动调用的component.getMenu()。
注意点
- 确保测试中不再主动调用
component.getMenu(),避免不必要的执行 - 若选择方案1,后续测试其他函数时,环境变量的设置不会影响非
ngOnInit内的函数测试
内容的提问来源于stack exchange,提问作者Alen Aju
相关产品推荐
相关产品推荐

