Jest下测试Angular+NGXS Router/Store组件时路由跳转不符合预期
NGXS命名路由跳转单元测试异常解决方案
问题根因定位
你遇到的是测试环境下NGXS Router与Angular路由状态不同步、配置缺失导致的命名outlet不生效问题,线上逻辑正常说明业务代码无误,只需调整测试用例的初始化、配置和断言逻辑即可。
具体修复步骤
- 第一步:补全测试模块的路由配置
测试环境的路由配置必须完整定义命名outlet对应的路径规则,否则NGXS Router找不到side outlet的匹配规则,会默认将路径挂载到primary outlet上,参考配置:const testRoutes = [ { path: 'view', children: [ { path: 'list', component: MockListComponent }, { path: 'add/targets', component: MockAddTargetsComponent, outlet: 'side' } ] } ]; // 测试模块导入 imports: [ RouterTestingModule.withRoutes(testRoutes), NgxsModule.forRoot([]), NgxsRouterPluginModule.forRoot() // 必须导入路由插件 ] - 第二步:修正路由状态初始化逻辑
不要在beforeEach中直接手动修改Store里的RouterState.url,这种方式只会改Store快照,不会同步更新Angular的真实路由树,后续跳转的路径计算会基于错误的路由树执行。改用Navigateaction完成初始路由跳转:beforeEach(async () => { // 等待初始路由跳转完成 await store.dispatch(new Navigate(['/view/(list//side:home)'])).toPromise(); fixture.detectChanges(); }); - 第三步:异步等待跳转完成后再断言
NGXS的Navigateaction是异步执行的,点击按钮后直接断言会拿到跳转前的旧状态,需要等待异步任务执行完成后再做校验:// 点击下一步按钮 const nextBtn = fixture.debugElement.query(By.css('.next-btn')); nextBtn.nativeElement.click(); fixture.detectChanges(); // 等待路由状态更新 await store.selectOnce(RouterState.url).pipe(filter(url => url !== page1Url)).toPromise(); // 执行断言 expect(store.selectSnapshot(RouterState.url)).toBe('/view/(list//side:add/targets)'); - 第四步:校验相对路由参数配置
如果业务代码的Navigateaction用了relativeTo参数绑定当前组件的ActivatedRoute,需要在测试模块中为ActivatedRoute提供正确的Mock值,或者直接改用绝对路径跳转,避免相对路径计算错误。
内容的提问来源于stack exchange,提问作者Ollie Webb
相关产品推荐
相关产品推荐

