Пытаюсь ознакомиться с юнит-тестированием маршрутного охранника. У меня есть относительно простая защита, которая получает значение от субъекта asObservable либо для созданияUrlTree, либо для возврата логического значения.
В отладчике браузера я не могу войти в функцию карты, чтобы увидеть какие-либо значения, и мои тесты не удались, потому что шпионский метод никогда не вызывался. Заранее благодарим вас за любую помощь или понимание.
сторожить
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();
});
Вам необходимо подписаться на охранника, поскольку он возвращает наблюдаемый поток.
Я использую 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();
});
Подписка - это то, чего мне здесь не хватало. Чтобы удовлетворить машинопись в моей IDE, мне нужно было создать ссылку и привести ее к вызову подписки... const canActivate = ExecuteGuard(activatedRoute.snapshot, {} as RouterStateSnapshot) as Observable<boolean>; canActivate.subscribe();