You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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) 

错误原因分析

  1. 缺失关键服务的Mock:VesselManagementService的构造函数依赖AppConfigService,并调用其getConfig()方法获取baseURL,但测试模块中没有提供AppConfigService的Mock实现,导致configService.getConfig()返回undefined,读取baseURL时触发错误。
  2. 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 19:36:02