Angular 16 路由保护单元测试可观察的 createSpyObj 属性

问题描述 投票:0回答:1

尝试熟悉路由守卫的单元测试。我有一个相对直接的防护,它从主题 asObservable 获取值到 createUrlTree 或返回布尔值。

在浏览器调试器中,我无法进入映射函数以查看任何值,并且我的测试失败,因为从未调用间谍方法。预先感谢您的任何帮助或见解。

守卫

  export const loginGuard: CanActivateFn = () => {
  const userService: UserService = inject(UserService);
  const router: Router = inject(Router);

  return userService.isLoggedIn$
    .pipe(
      take(1),
      map(loggedIn => {
        return loggedIn ? router.createUrlTree(['/dashboard']) : true;
      }));
};

测试

  const executeGuard: CanActivateFn = (...guardParameters) =>
    TestBed.runInInjectionContext(() => loginGuard(...guardParameters));
  const mockRouter = jasmine.createSpyObj('Router', ['createUrlTree']);
  const mockUserService = jasmine.createSpyObj('UserService', [], {isLoggedIn$: of(true)});
  let activatedRoute: ActivatedRoute;
  beforeEach(() => {
    TestBed.configureTestingModule({
      providers: [
        {provide: Router, useValue: mockRouter},
        {provide: UserService, useValue: mockUserService},
        {
          provide: ActivatedRoute,
          useValue: {
            snapshot: {}
          }
        }
      ]
    });
    activatedRoute = TestBed.inject(ActivatedRoute);
  });

  it('should redirect to dashboard', () => {
    executeGuard(activatedRoute.snapshot, {} as RouterStateSnapshot);
    expect(mockRouter.createUrlTree).toHaveBeenCalledWith('/dashboard');
  });

  it('should proceed to login', () => {
    mockUserService.isLoggedIn$ = of(false);
    const canActivate = executeGuard(activatedRoute.snapshot, {} as RouterStateSnapshot);
    expect(canActivate).toBeTruthy();
  });
angular unit-testing jasmine karma-jasmine
1个回答
0
投票

您需要订阅守卫,因为它返回一个可观察的流!

我使用

fakeAsync
flush
等待订阅完成,这可能是可选的,但拥有它很好!

  it('should redirect to dashboard', fakeAsync(() => {
    executeGuard(activatedRoute.snapshot, 
        {} as RouterStateSnapshot).subscribe(); // <- changed here!
    flush();
    expect(mockRouter.createUrlTree).toHaveBeenCalledWith('/dashboard');
  }));

  it('should proceed to login', () => {
    mockUserService.isLoggedIn$ = of(false);
    const canActivate = executeGuard(activatedRoute.snapshot, {} as RouterStateSnapshot);
    expect(canActivate).toBeTruthy();
  });
© www.soinside.com 2019 - 2024. All rights reserved.