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

Angular 18:懒加载模块单元测试替代SpyNgModuleFactoryLoader方案咨询

测试带canMatch守卫的懒加载模块(Angular 13+)

路由配置示例(截图内容):包含canMatch守卫与loadChildren的懒加载路由定义,例如:

{
  path: 'auth',
  canMatch: [AuthGuard],
  loadChildren: () => import('./auth/auth.module').then(m => m.AuthModule)
}

针对SpyNgModuleFactoryLoader已废弃的情况,以下是Angular 13+版本测试带loadChildren的懒加载模块的替代方案:

1. 用RouterTestingModule.withRoutes模拟路由逻辑

无需真实加载懒加载模块,直接通过RouterTestingModule提供模拟路由,配合mock守卫实现,验证导航行为:

import { TestBed } from '@angular/core/testing';
import { RouterTestingModule } from '@angular/router/testing';
import { Router, Location } from '@angular/common';
import { provideMockStore } from '@ngrx/store/testing';
import { UserActions } from './store/user.actions';
import { MockData } from './mock.data';
import { AuthGuard } from './auth.guard';
// 定义空的mock组件用于测试
@Component({ template: '' })
class MockDashboardComponent {}

describe('Auth Route Navigation', () => {
  let router: Router;
  let location: Location;
  let store: MockStore;

  beforeEach(async () => {
    await TestBed.configureTestingModule({
      imports: [
        RouterTestingModule.withRoutes([
          {
            path: 'auth',
            canMatch: [AuthGuard],
            children: [
              { path: 'dashboard', component: MockDashboardComponent },
              { path: '', redirectTo: 'dashboard', pathMatch: 'full' }
            ]
          }
        ])
      ],
      declarations: [MockDashboardComponent],
      providers: [
        provideMockStore(),
        // 若需mock守卫逻辑,可替换为自定义实现
        // { provide: AuthGuard, useValue: { canMatch: () => Promise.resolve(true) } }
      ]
    }).compileComponents();

    router = TestBed.inject(Router);
    location = TestBed.inject(Location);
    store = TestBed.inject(MockStore);
    await router.initialNavigation();
  });

  it('导航到"auth"时重定向到/auth/dashboard', async () => {
    store.dispatch(UserActions.loginSuccess({ data: MockData.UserLoggedIn }));
    await router.navigate(['auth']);
    expect(location.path()).toBe('/auth/dashboard');
  });
});

2. 使用RouterTestingHarness(Angular 14+)

Angular 14+推出的RouterTestingHarness简化了路由测试流程,适合复杂场景:

import { TestBed } from '@angular/core/testing';
import { RouterTestingHarness } from '@angular/router/testing';
import { provideRoutes } from '@angular/router';
import { provideMockStore } from '@ngrx/store/testing';
import { UserActions } from './store/user.actions';
import { MockData } from './mock.data';
import { AuthGuard } from './auth.guard';
@Component({ template: '' })
class MockDashboardComponent {}

describe('Auth Route Navigation', () => {
  let harness: RouterTestingHarness;
  let store: MockStore;

  beforeEach(async () => {
    await TestBed.configureTestingModule({
      declarations: [MockDashboardComponent],
      providers: [
        provideMockStore(),
        provideRoutes([
          {
            path: 'auth',
            canMatch: [AuthGuard],
            children: [
              { path: 'dashboard', component: MockDashboardComponent },
              { path: '', redirectTo: 'dashboard', pathMatch: 'full' }
            ]
          }
        ])
      ]
    }).compileComponents();

    store = TestBed.inject(MockStore);
    harness = await RouterTestingHarness.create();
  });

  it('导航到"auth"时重定向到/auth/dashboard', async () => {
    store.dispatch(UserActions.loginSuccess({ data: MockData.UserLoggedIn }));
    await harness.navigateByUrl('/auth');
    expect(harness.location.path()).toBe('/auth/dashboard');
  });
});

3. MockloadChildren加载函数

如果需要验证loadChildren的触发逻辑,可以直接mock其返回值,避免真实加载模块:

// 在路由配置中mock loadChildren
RouterTestingModule.withRoutes([
  {
    path: 'auth',
    canMatch: [AuthGuard],
    // Mock懒加载模块加载,返回Promise包装的mock模块
    loadChildren: () => Promise.resolve({
      ngModule: class MockAuthModule {},
      providers: []
    })
  }
])

核心注意事项

  • 无需依赖废弃的SpyNgModuleFactoryLoader,通过模拟路由或mock守卫即可完成测试
  • canMatch守卫的逻辑应单独编写单元测试,路由测试只需验证守卫结果对导航的影响
  • 使用async/await替代then回调,提升测试代码的可读性与稳定性

内容的提问来源于stack exchange,提问作者chetan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 13:27:24