Angular单元测试模拟router.events.subscribe报错求助
Angular单元测试模拟router.events.subscribe报错解决
问题场景
在Angular单元测试中手动模拟Router对象的events时,触发错误:TypeError: Cannot read properties of undefined (reading 'root'),相关代码如下:
组件TS代码
ngOnInit(): void { this.router.events.subscribe(event => { this.splitRoutes(); }); } private splitRoutes() { const routes = this.router.url.toString().split('/'); // 其他业务逻辑 }
测试spec.ts代码
beforeEach(async () => { await TestBed.configureTestingModule({ imports: [], providers: [{ provide: Router, useValue: { url: '/non-pdp/phases/8', events: of( new NavigationEnd(0, 'http://localhost:4200/#/non-pdp/phases/8', 'http://localhost:4200/#/non-pdp/phases/8')), navigate: jasmine.createSpy('navigate') }], }) .compileComponents(); });
错误原因
手动模拟的Router对象缺少Angular内部处理路由事件时依赖的属性(比如routerState.root),虽然你的组件代码没有直接调用这些属性,但Angular在订阅router.events的内部逻辑中会访问它们,导致未定义报错。
解决方案
方案一:完善Router模拟对象
给模拟的Router补充routerState和root属性,满足Angular内部逻辑的访问需求:
beforeEach(async () => { await TestBed.configureTestingModule({ imports: [], providers: [{ provide: Router, useValue: { url: '/non-pdp/phases/8', events: of( new NavigationEnd(0, 'http://localhost:4200/#/non-pdp/phases/8', 'http://localhost:4200/#/non-pdp/phases/8')), navigate: jasmine.createSpy('navigate'), // 添加缺失的路由状态属性 routerState: { root: {} } }], }) .compileComponents(); });
方案二:使用RouterTestingModule(推荐)
Angular官方提供的RouterTestingModule会自动配置完整的Router测试环境,避免手动模拟遗漏属性的问题:
import { RouterTestingModule } from '@angular/router/testing'; beforeEach(async () => { await TestBed.configureTestingModule({ // 导入RouterTestingModule,可根据需求配置测试路由 imports: [RouterTestingModule.withRoutes([])], // 无需手动提供Router,模块会自动注入测试用实例 providers: [], }) .compileComponents(); // 获取Router实例并自定义url和events const router = TestBed.inject(Router); spyOnProperty(router, 'url').and.returnValue('/non-pdp/phases/8'); router.events = of( new NavigationEnd(0, 'http://localhost:4200/#/non-pdp/phases/8', 'http://localhost:4200/#/non-pdp/phases/8') ); });
使用RouterTestingModule的优势在于它会模拟完整的Router上下文,包括路由状态、导航行为等,后续如果组件用到更多Router的属性或方法,无需手动补充模拟,稳定性更强。
内容的提问来源于stack exchange,提问作者denisiulian
相关产品推荐
相关产品推荐

