Angular 15升级至15.1后执行测试出现afterAll未定义属性读取错误
Angular 15.1单元测试报错:Cannot read properties of undefined (reading 'A')
问题背景
将Angular项目从15升级至15.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 'A') TypeError: Cannot read properties of undefined (reading 'A') at Object.2494 (http://localhost:9877/_karma_webpack_/webpack:/src/app/storage-service.service.ts:8:52) at __webpack_require__ (http://localhost:9877/_karma_webpack_/webpack:/webpack/bootstrap:19:1) at Object.283 (http://localhost:9877/_karma_webpack_/main.js:86:82) at __webpack_require__ (http://localhost:9877/_karma_webpack_/webpack:/webpack/bootstrap:19:1) at __webpack_exec__ (http://localhost:9877/_karma_webpack_/main.js:186:48) at http://localhost:9877/_karma_webpack_/main.js:187:126 at Function.__webpack_require__.O (http://localhost:9877/_karma_webpack_/webpack:/webpack/runtime/chunk loaded:23:1) at http://localhost:9877/_karma_webpack_/main.js:188:56 at webpackJsonpCallback (http://localhost:9877/_karma_webpack_/webpack:/webpack/runtime/jsonp chunk loading:34:1)
通过CLI创建新的Angular15.1项目,生成语义一致的StorageServiceService可复现问题:
服务代码
import { Injectable } from '@angular/core'; @Injectable({ providedIn: 'root' }) export class StorageServiceService { public static readonly A = 'a'; public static readonly B = StorageServiceService.A + 'b'; public static readonly C = StorageServiceService.A + 'c'; constructor() { } }
测试代码
import { TestBed } from '@angular/core/testing'; import { StorageServiceService } from './storage-service.service'; describe('StorageServiceService', () => { let service: StorageServiceService; beforeEach(() => { TestBed.configureTestingModule({}); service = TestBed.inject(StorageServiceService); }); it('should be created', () => { expect(service).toBeTruthy(); }); it('test', () => { expect(StorageServiceService.A).toEqual('a') expect(StorageServiceService.B).toEqual('ab') expect(StorageServiceService.C).toEqual('ac') }) });
当前环境配置:
- Node 18.12.1、npm 9.2.0
- package.json依赖版本:
{ "name": "test-app", "version": "0.0.0", "scripts": { "ng": "ng", "start": "ng serve", "build": "ng build", "watch": "ng build --watch --configuration development", "test": "ng test" }, "private": true, "dependencies": { "@angular/animations": "^15.1.0", "@angular/common": "^15.1.0", "@angular/compiler": "^15.1.0", "@angular/core": "^15.1.0", "@angular/forms": "^15.1.0", "@angular/platform-browser": "^15.1.0", "@angular/platform-browser-dynamic": "^15.1.0", "@angular/router": "^15.1.0", "rxjs": "~7.8.0", "tslib": "^2.3.0", "zone.js": "~0.12.0" }, "devDependencies": { "@angular-devkit/build-angular": "^15.1.1", "@angular/cli": "~15.1.1", "@angular/compiler-cli": "^15.1.0", "@types/jasmine": "~4.3.0", "jasmine-core": "~4.5.0", "karma": "~6.4.0", "karma-chrome-launcher": "~3.1.0", "karma-coverage": "~2.2.0", "karma-jasmine": "~5.1.0", "karma-jasmine-html-reporter": "~2.0.0", "typescript": "~4.9.4" } }
降级回Angular 15版本后测试可正常执行,升级操作通过Angular CLI完成,未手动修改配置。
解决方案
方案1:修改静态属性引用方式
将静态属性中对类名的直接引用替换为this,在静态属性初始化阶段,this指向类构造函数本身,可安全访问已定义的静态属性:
import { Injectable } from '@angular/core'; @Injectable({ providedIn: 'root' }) export class StorageServiceService { public static readonly A = 'a'; // 使用this替代类名访问静态属性 public static readonly B = this.A + 'b'; public static readonly C = this.A + 'c'; constructor() { } }
方案2:提取静态常量到类外部
将相关常量移至类外的独立对象中,彻底避免类初始化顺序问题:
// 提取常量到类外部 export const STORAGE_CONSTANTS = { A: 'a', B: STORAGE_CONSTANTS.A + 'b', C: STORAGE_CONSTANTS.A + 'c' }; @Injectable({ providedIn: 'root' }) export class StorageServiceService { constructor() { } }
对应的测试代码需同步修改为引用外部常量:
import { TestBed } from '@angular/core/testing'; import { StorageServiceService, STORAGE_CONSTANTS } from './storage-service.service'; describe('StorageServiceService', () => { let service: StorageServiceService; beforeEach(() => { TestBed.configureTestingModule({}); service = TestBed.inject(StorageServiceService); }); it('should be created', () => { expect(service).toBeTruthy(); }); it('test', () => { expect(STORAGE_CONSTANTS.A).toEqual('a') expect(STORAGE_CONSTANTS.B).toEqual('ab') expect(STORAGE_CONSTANTS.C).toEqual('ac') }) });
方案3:临时降级或等待官方修复
该问题是Angular 15.1版本打包时的类初始化顺序bug,若不想修改代码,可选择:
- 降级回Angular 15.0.x版本
- 等待Angular官方发布修复版本
内容的提问来源于stack exchange,提问作者mchl_bld
相关产品推荐
相关产品推荐

