try 熟悉路由警卫的单元测试.我有一个相对直接的后卫,它从主题asObservable获取一个值,以初始化UrlTree或返回布尔值.

在浏览器调试器中,我无法进入map函数来查看任何值,并且我的测试失败,因为从未调用过间谍方法.提前感谢您的任何帮助或见解.

guard

  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;
      }));
};

test

  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();
  });

推荐答案

您需要订阅guard,因为它返回可观察流!

我使用fakeAsyncflush来等待订阅完成,这可能是可选的,但拥有它很好!

  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();
  });

Angular相关问答推荐

如何取消针叶林输入的自动填充?

Angular 17自定义指令渲染不起作用'

TransLoco合并本地和服务器端转换对象

material 对话框中没有合适的注塑

所有返回缺少权限或权限不足的FireBase项目.

NG-Zorro Datepicker 手动输入掩码不起作用

JsPDF Autotable 将图像添加到列中出现错误:属性getElementsByTagName不存在

使用 primeng Apollo 主题进行实时部署时多次加载 theme.css 和 preloading.css 文件

如何在Angular中自动路由到子路由

无法读取 angular2 中未定义(…)的属性 push

Springboot/Angular2 - 如何处理 HTML5 url?

Angular 4.3拦截器不起作用

使用 Jasmine 和 Karma 对 Angular 进行单元测试,错误:无法绑定到xxx,因为它不是xxxxxx的已知属性.

相对于根目录的 SCSS 导入

Angular 4:InvalidPipeArgument:管道AsyncPipe的[object Object]

为什么我们需要`ngDoCheck`

Angular2:如果 img src 无效,则显示占位符图像

Angular2 Base64 清理不安全的 URL 值

检测指令中输入值何时更改

如何在 Angular 中使用带有 SASS 的 Bootstrap 4