Angular测试报错:Cannot read properties of undefined (reading 'baseURL') 求助
问题:Angular守卫测试中出现Cannot read properties of undefined (reading 'baseURL')错误
我是Angular新手,在测试VesselManagementGuard组件时遇到TypeError: Cannot read properties of undefined (reading 'baseURL')错误,尽管已在测试文件中添加了Mock服务,仍然出现该错误。请帮我理解错误原因并提供解决方案。
相关代码文件
VesselManagementGuard.ts
import { Injectable } from '@angular/core'; import { Resolve} from '@angular/router'; import { VesselManagementService } from '../services/vessel-management.service'; @Injectable({ providedIn: 'root' }) export class VesselManagementGuard implements Resolve<any> { constructor(public vesselManagementService: VesselManagementService) { } resolve() { return this.vesselManagementService.getvesselManagement() } }
VesselManagementGuard.spec.ts
import { HttpClientTestingModule } from '@angular/common/http/testing'; import { TestBed } from '@angular/core/testing'; import { MatDialogRef } from '@angular/material/dialog'; import { VesselManagementGuard } from './vessel-management.guard'; import { CognitoService } from 'src/app/modules/auth/cognito.service'; describe('VesselManagementGuard', () => { let guard: VesselManagementGuard; beforeEach(() => { TestBed.configureTestingModule({ imports: [HttpClientTestingModule], providers: [ { provide: MatDialogRef, CognitoService, useValue: { getConfig: () => ({ baseUrl: 'any', //Added mock of the service here still getting the error serviceBase: 'any' }) } } ], }); guard = TestBed.inject(VesselManagementGuard); }); it('should be created', () => { expect(guard).toBeTruthy(); }); });
vessel.management.service.ts
import { HttpClient } from '@angular/common/http'; import { Injectable } from '@angular/core'; import { Observable } from 'rxjs/internal/Observable'; import { CognitoService } from 'src/app/modules/auth/cognito.service'; import { AppConfigService } from 'src/app/services/config/app-config.service'; @Injectable({ providedIn: 'root', }) export class VesselManagementService { baseURL: any; serviceBase: any; userEmail:string=''; constructor( private httpClient: HttpClient, private configService: AppConfigService, private cognitoService: CognitoService ) { this.baseURL = this.configService.getConfig().baseURL; //configService method has been called here this.serviceBase = this.configService.getConfig().serviceBase; } getvesselManagement(): Observable<any[]> { const userEmail=sessionStorage.getItem('email'); return this.httpClient.get<any[]>( this.baseURL + this.serviceBase + 'useradmin/vessels?email='+userEmail ); } postvesselManagement(postData: any): Observable<any[]> { return this.httpClient.post<any>(this.baseURL + this.serviceBase + `useradmin/vessel`, postData); } }
错误信息
VesselManagementGuard > should be created TypeError: Cannot read properties of undefined (reading 'baseURL') TypeError: Cannot read properties of undefined (reading 'baseURL') at new VesselManagementService (http://localhost:9876/_karma_webpack_/webpack:/src/app/modules/pages/vessel-management/services/vessel-management.service.ts:19:50) at Object.VesselManagementService_Factory [as factory] (ng:///VesselManagementService/ɵfac.js:4:10) at R3Injector.hydrate (http://localhost:9876/_karma_webpack_/webpack:/node_modules/@angular/core/fesm2015/core.mjs:11457:1) at R3Injector.get (http://localhost:9876/_karma_webpack_/webpack:/node_modules/@angular/core/fesm2015/core.mjs:11276:1) at injectInjectorOnly (http://localhost:9876/_karma_webpack_/webpack:/node_modules/@angular/core/fesm2015/core.mjs:4765:1) at ɵɵinject (http://localhost:9876/_karma_webpack_/webpack:/node_modules/@angular/core/fesm2015/core.mjs:4769:1) at Object.VesselManagementGuard_Factory [as factory] (ng:///VesselManagementGuard/ɵfac.js:4:49) at R3Injector.hydrate (http://localhost:9876/_karma_webpack_/webpack:/node_modules/@angular/core/fesm2015/core.mjs:11457:1) at R3Injector.get (http://localhost:9876/_karma_webpack_/webpack:/node_modules/@angular/core/fesm2015/core.mjs:11276:1) at NgModuleRef.get (http://localhost:9876/_karma_webpack_/webpack:/node_modules/@angular/core/fesm2015/core.mjs:21832:1) Expected undefined to be truthy. Error: Expected undefined to be truthy. at <Jasmine> at UserContext.<anonymous> (http://localhost:9876/_karma_webpack_/webpack:/src/app/modules/pages/vessel-management/resolver/vessel-management.guard.spec.ts:32:19) at _ZoneDelegate.invoke (http://localhost:9876/_karma_webpack_/webpack:/node_modules/zone.js/fesm2015/zone.js:372:1) at ProxyZoneSpec.onInvoke (http://localhost:9876/_karma_webpack_/webpack:/node_modules/zone.js/fesm2015/zone-testing.js:287:1)
错误原因分析
- 缺失关键服务的Mock:
VesselManagementService的构造函数依赖AppConfigService,并调用其getConfig()方法获取baseURL,但测试模块中没有提供AppConfigService的Mock实现,导致configService.getConfig()返回undefined,读取baseURL时触发错误。 - Provider配置格式错误:测试文件中把
MatDialogRef、CognitoService和Mock值写在同一个provider对象里,这不符合Angular测试配置的规范,每个服务的Mock需要单独定义provider。
解决方案
修改测试文件,为所有依赖服务提供正确的Mock实现,尤其是AppConfigService:
修改后的VesselManagementGuard.spec.ts
import { HttpClientTestingModule } from '@angular/common/http/testing'; import { TestBed } from '@angular/core/testing'; import { MatDialogRef } from '@angular/material/dialog'; import { VesselManagementGuard } from './vessel-management.guard'; import { CognitoService } from 'src/app/modules/auth/cognito.service'; import { AppConfigService } from 'src/app/services/config/app-config.service'; // 引入AppConfigService describe('VesselManagementGuard', () => { let guard: VesselManagementGuard; beforeEach(() => { TestBed.configureTestingModule({ imports: [HttpClientTestingModule], providers: [ // 单独为MatDialogRef提供Mock { provide: MatDialogRef, useValue: {} }, // 为CognitoService提供Mock(如果测试中不需要具体方法,可留空对象) { provide: CognitoService, useValue: {} }, // 关键:为AppConfigService提供包含getConfig方法的Mock { provide: AppConfigService, useValue: { getConfig: () => ({ baseURL: 'any', serviceBase: 'any' }) } } ], }); guard = TestBed.inject(VesselManagementGuard); }); it('should be created', () => { expect(guard).toBeTruthy(); }); });
修改说明
- 新增
AppConfigService的Mock provider,确保其getConfig()方法返回包含baseURL和serviceBase的对象,匹配VesselManagementService中的调用逻辑。 - 拆分原错误格式的provider,每个依赖服务单独定义Mock,符合Angular测试配置规范。
- 为
MatDialogRef和CognitoService提供基础Mock,避免注入时出现未定义的情况。
内容的提问来源于stack exchange,提问作者Mayuri Jadhav
相关产品推荐
相关产品推荐

