Angular 15.1升级后含静态数据的组件单元测试失败求助
Angular 15.1升级后单元测试静态属性读取失败问题解决
问题描述
Angular 15.0项目升级至15.1后,执行yarn test-coverage触发单元测试失败,ZoomControlComponent组件报以下错误:
Uncaught TypeError: Cannot read properties of undefined (reading 'PredefinedZoomEnumMapList')
组件中定义了静态属性PredefinedZoomEnumMapList,并通过类名直接引用它来初始化另一个静态属性PredefinedZoomEnumLabelList。
组件代码片段
@Component({ selector: 'mad-zoom-control', templateUrl: './zoom-control.component.html', styleUrls: ['./zoom-control.component.scss'] }) export class ZoomControlComponent extends MadComponent implements OnInit, OnChanges, AfterViewInit { @Input() conserveRatio = true; @Input() dropupPredefinedOption = true; @Input() showPredefined = true; @Input() showZoomFactor = true; @Input() zone: Zone = null; @Output() readonly zoomChanged = new EventEmitter<boolean>(); // Predefined Zoom -> Predefined Zoom Label static PredefinedZoomEnumMapList = [ ['full', MAD_FULL], ['center', MAD_MenuPositionEnum_eCENTER], ['left', MAD_ZoneJustifyXEnum_eLEFT], ['right', MAD_ZoneJustifyXEnum_eRIGHT], ['top', MAD_ZoneJustifyXEnum_eTOP], ['bottom', MAD_ZoneJustifyXEnum_eBOTTOM], ['topLeft', MAD_MenuPositionEnum_eTOP_LEFT], ['topRight', MAD_MenuPositionEnum_eTOP_RIGHT], ['bottomLeft', MAD_MenuPositionEnum_eBOTTOM_LEFT], ['bottomRight', MAD_MenuPositionEnum_eBOTTOM_RIGHT], ]; static PredefinedZoomEnumLabelList = ZoomControlComponent.PredefinedZoomEnumMapList.map((zoneAspect) => zoneAspect[1]); }
报错信息
Chrome 109.0.0.0 (Mac OS 10.15.7) ERROR An error was thrown in afterAll Uncaught TypeError: Cannot read properties of undefined (reading 'PredefinedZoomEnumMapList') TypeError: Cannot read properties of undefined (reading 'PredefinedZoomEnumMapList') at http://localhost:9876/_karma_webpack_/webpack:/src/app/widgets/zoom-control/zoom-control.component.ts:60:61 at Module.13225 (http://localhost:9876/_karma_webpack_/webpack:/src/app/widgets/zoom-control/zoom-control.component.ts:60:122)
解决方案
原因分析
Angular 15.1的测试编译逻辑调整了类静态属性的初始化顺序,导致在初始化PredefinedZoomEnumLabelList时,ZoomControlComponent类本身还未完全初始化,直接通过类名引用静态属性会出现undefined。
修复方法
方法1:使用this替代类名引用静态属性
在静态属性初始化中,用this指向当前类,避免直接引用类名:
static PredefinedZoomEnumMapList = [/* 原有数组内容 */]; static PredefinedZoomEnumLabelList = this.PredefinedZoomEnumMapList.map((zoneAspect) => zoneAspect[1]);
方法2:改用静态getter延迟计算
将PredefinedZoomEnumLabelList改为静态getter,确保在访问时才计算值:
static PredefinedZoomEnumMapList = [/* 原有数组内容 */]; static get PredefinedZoomEnumLabelList() { return this.PredefinedZoomEnumMapList.map((zoneAspect) => zoneAspect[1]); }
方法3:检查测试文件的mock配置
如果测试中对ZoomControlComponent进行了mock,确保mock没有覆盖静态属性,或者在测试前手动初始化组件类:
// 在测试文件的beforeEach中添加 import { ZoomControlComponent } from './zoom-control.component'; beforeEach(() => { // 确保组件类被正确加载 ZoomControlComponent; // 其他测试配置 });
内容的提问来源于stack exchange,提问作者Cyberbougnat
相关产品推荐
相关产品推荐

