尝试熟悉路由守卫的单元测试。我有一个相对直接的防护,它从主题 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();
});
您需要订阅守卫,因为它返回一个可观察的流!
我使用
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();
});