如何为children分支内的懒加载路由编写测试用例以实现100%代码覆盖率?
解决Angular路由children中懒加载路由的代码覆盖率问题
问题场景
我的路由配置包含嵌套children的懒加载路由:
{ path: '', children: [ { path: 'dashboard', loadChildren: () => import('./modules/dashboard/dashboardv10.module').then((m) => m.Dashboardv10Module), } ], }
我编写了对应的懒加载导航测试用例,测试能正常通过,但children里的路由代码始终无法计入代码覆盖率:
it('Should lazily navigate to Dashboard Component', fakeAsync(() =>{ const loader = TestBed.inject(SpyNgModuleFactoryLoader); loader.stubbedModules = {lazyModule: Dashboardv10Module }; router.navigateByUrl('/dashboard'); tick(); fixture.detectChanges(); expect(location.path()).toEqual('/dashboard'); }));
该测试在非嵌套路由场景下正常,但嵌套children的路由无法触发覆盖率统计。
解决方案
1. 确保测试路由配置完整包含父路由结构
在RouterTestingModule.withRoutes中,必须完整传入包含children的父路由配置,不能只单独配置子路由:
TestBed.configureTestingModule({ imports: [ RouterTestingModule.withRoutes([ // 完整复制生产环境的路由结构 { path: '', children: [ { path: 'dashboard', loadChildren: () => import('./modules/dashboard/dashboardv10.module').then(m => m.Dashboardv10Module) } ] } ]) ], // 其他测试依赖配置 });
2. 匹配实际的懒加载模块路径进行Stub
不要用lazyModule这种通用名称,必须和路由中loadChildren的导入路径完全匹配:
it('Should lazily load Dashboard module via parent route children', fakeAsync(() => { const loader = TestBed.inject(SpyNgModuleFactoryLoader); // 路径要和loadChildren里的import路径完全一致 loader.stubbedModules['./modules/dashboard/dashboardv10.module#Dashboardv10Module'] = Dashboardv10Module; router.navigateByUrl('/dashboard'); tick(); fixture.detectChanges(); // 验证导航路径 expect(location.path()).toEqual('/dashboard'); // 额外验证children路由是否被正确识别(确保覆盖率统计触发) const parentRoute = router.config.find(route => route.path === ''); expect(parentRoute.children?.length).toBeGreaterThan(0); const dashboardRoute = parentRoute.children?.find(child => child.path === 'dashboard'); expect(dashboardRoute).toBeTruthy(); }));
原理说明
代码覆盖率工具需要检测到路由配置对象(包括children数组)被Angular的Router模块读取和处理。之前的测试中,要么路由配置不完整,要么Stub的模块路径不匹配,导致children里的路由声明未被标记为已执行。通过完整传入路由结构并匹配真实导入路径,确保路由初始化时children配置被正确解析,从而计入覆盖率。
内容的提问来源于stack exchange,提问作者Rajesh Sah
相关产品推荐
相关产品推荐

