I have a guard that tests if the user is logged in or not and check his user context
export function authenticationGuard(userContext: UserContextService): CanActivateFn {
return async (_next: ActivatedRouteSnapshot, state: RouterStateSnapshot) => {
const userService: UserService = inject(UserService);
const router: Router = inject(Router);
const cognitoService: CognitoService = inject(CognitoService);
if(await cognitoService.currentAuthenticatedUser()){
if(userContext.getUserInfos() === undefined || userContext.getUserInfos() === null || Object.keys(userContext.getUserInfos()).length === 0){
const userInfo$ = userService.getCurrentUserInfos();
userContext.setUserInfos(await lastValueFrom(userInfo$));
}
return true;
}else{
localStorage.setItem('redirect', JSON.stringify(state.url));
router.navigate(['authentification']);
return false;
}
};
}
I Write unit test :
describe('authenticationGuard', () => {
let cognitoServiceSpy: jasmine.SpyObj<CognitoService>;
let userContextServiceSpy: jasmine.SpyObj<UserContextService>;
let userServiceSpy: jasmine.SpyObj<UserService>;
let activatedRoute: jasmine.SpyObj<ActivatedRoute>;
let routerState: jasmine.SpyObj<RouterState>;
let mockRouter = {
navigate: jasmine.createSpy('navigate')
};
beforeEach(() => {
cognitoServiceSpy = jasmine.createSpyObj('CognitoService', ['currentAuthenticatedUser']);
userServiceSpy = jasmine.createSpyObj('UserService', ['getCurrentUserInfos']);
userContextServiceSpy = jasmine.createSpyObj('UserContextService', ['getUserInfos', 'setUserInfos']);
activatedRoute = jasmine.createSpyObj('ActivatedRoute', [], {'snapshot': {}});
routerState = jasmine.createSpyObj('RouterState', [], {'snapshot': {}});
TestBed.configureTestingModule({
imports: [RouterTestingModule],
providers: [
{ provide: CognitoService, useValue: cognitoServiceSpy },
{ provide: UserService, useValue: userServiceSpy },
{ provide: UserContextService, useValue: userContextServiceSpy },
{ provide: Router, useValue: mockRouter },
{ provide: ActivatedRoute, useValue: activatedRoute },
{ provide: RouterState, useValue: routerState }
]
});
});
it('should be created', fakeAsync(() => {
cognitoServiceSpy.currentAuthenticatedUser.and.resolveTo(false);
const executeGuard: any = TestBed.runInInjectionContext(() => {
return authenticationGuard(userContextServiceSpy);
});
tick();
expect(mockRouter.navigate).toHaveBeenCalled();
expect(executeGuard).toBeFalse();
}));
});
The result is Expected Function to be false.
I don't understand the problem.
How to test my guard. I want the to abocrd test the case when the user is not logged in
Your guard is async, it's effectivly returning a
Promise<boolean>, not a promise.Also, your should be returning a
UrlTreeinstead of navigating + returningfalse:So
should be replaced by