No tienes acceso a esta clase

¬°Contin√ļa aprendiendo! √önete y comienza a potenciar tu carrera

Pruebas a canActivate

12/20
Recursos

Aportes 3

Preguntas 0

Ordenar por:

¬ŅQuieres ver m√°s aportes, preguntas y respuestas de la comunidad?

Las pruebas a canActivate nos permitira ver como se ingresa a la ruta

Para poder hacer eso es necesario crear un archivo que simule fake Routes y fake states en nuestra carpeta testing

snapshot.ts

import { ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';

export function fakeRouterStateSnapshot(options: Partial<RouterStateSnapshot>) {
  return options as RouterStateSnapshot;
}

export function fakeActivatedStateSnapshot(options: Partial<ActivatedRouteSnapshot>) {
  return options as ActivatedRouteSnapshot;
}

para luego cargar esto en nuestro archivo de pruebas de guardianes

auth.guard.spec.ts

import { fakeActivatedStateSnapshot, fakeRouterStateSnapshot, mockObservable } from './../../testing';
import { generateOneUser } from '../models/user.mock';

it('should return true with session', (doneFn) => {
    const activatedRoute = fakeActivatedStateSnapshot({});
    const routerState = fakeRouterStateSnapshot({});
    const userMock = generateOneUser();

    authService.getUser.and.returnValue(mockObservable(userMock));
    guard.canActivate(activatedRoute, routerState)
    .subscribe(rta => {
      expect (rta).toBeTruthy();
      doneFn();
    });
  });

  it('should return true without session', (doneFn) => {
    const activatedRoute = fakeActivatedStateSnapshot({});
    const routerState = fakeRouterStateSnapshot({});
    authService.getUser.and.returnValue(mockObservable(null));
    guard.canActivate(activatedRoute, routerState)
    .subscribe(rta => {
      expect (rta).toBeFalse();
      expect (router.navigate).toHaveBeenCalledWith(['/home']);
      doneFn();
    });
  });
Al momento de realizar la prueba "should return true with session", estaba teniendo el siguiente problema con el .subscribe ![](https://static.platzi.com/media/user_upload/image-3fbff086-116b-43c6-8909-b3509643f493.jpg) Para solucionar el error de TypeScript, tuve que refactorizar el método canActivate para que siempre devuelva un Observable, ya que actualmente puede devolver un boolean o UrlTree directamente en algunas condiciones. De esta manera podemos usar en las pruebas el .suscribecanActivate(    route: ActivatedRouteSnapshot,    state: RouterStateSnapshot  ): Observable\<boolean | UrlTree> {    return this.authService.getUser().pipe(      map(user => {        if (!user) {          this.router.navigate(\['/home']);          return this.router.createUrlTree(\['/home']);        }        return true;      }),      catchError(() => {        this.router.navigate(\['/home']);        return of(this.router.createUrlTree(\['/home']));      })    );  }it('should return true with session', (doneFn) => {        const activatedRoute = fakeActivatedStateSnapshot({});        const routerState = fakeRouterStateSnapshot({});         const userMock = generateOneUser();        authService.getUser.and.returnValue(mockObservable(userMock));         guard.canActivate(activatedRoute, routerState).subscribe((rta: boolean | UrlTree) => {            expect(rta).toBeTrue();            doneFn();        });    }); Aca dejo el ajuste al código que realice en canActivate: ```ts canActivate( route: ActivatedRouteSnapshot, state: RouterStateSnapshot ): Observable<boolean | UrlTree> { return this.authService.getUser().pipe( map(user => { if (!user) { this.router.navigate(['/home']); return this.router.createUrlTree(['/home']); } return true; }), catchError(() => { this.router.navigate(['/home']); return of(this.router.createUrlTree(['/home'])); }) ); } ```Y asi quedaría la prueba: ```ts it('should return true with session', (doneFn) => { const activatedRoute = fakeActivatedStateSnapshot({}); const routerState = fakeRouterStateSnapshot({}); const userMock = generateOneUser(); authService.getUser.and.returnValue(mockObservable(userMock)); guard.canActivate(activatedRoute, routerState).subscribe((rta: boolean | UrlTree) => { expect(rta).toBeTrue(); doneFn(); }); }); ```

Para poder hacer testing de propiedades en Jasmine, pueden hacer lo siguiente:

  1. Definir las propiedades deseadas en el espía:

    const authServiceSpyObj = jasmine.createSpyObj<AuthService>(
    	'AuthService',
    	[// Mehods here],
    	{
    		user$: observableData(generateOneUser()),
    		// Other properties with his value
    	}
    );
    
  2. Reemplazar el provider con nuestro espía:

    TestBed.configureTestingModule({
    	providers: [
    		AuthGuard,
    		{
    			provide: AuthService,
    			useValue: authServiceSpyObj,
    		},
    	],
    });
    
  3. Inyectamos nuestro provider:

    authServiceSpy = TestBed.inject(AuthService) as jasmine.SpyObj<AuthService>;
    
  4. Definimos nuestras pruebas:

    it('should return true if user is logged in', waitForAsync(() => {
    	const route = fakeActivatedRouteSnapshot({});
    	const state = fakeRouterStateSnapshot({});
    
    	guard.canActivate(route, state).subscribe({
    		next: (value) => {
    		expect(value).toBeTrue();
    		},
    	});
    }));
    
    it("should return false if user isn't logged in", waitForAsync(() => {
    	const route = fakeActivatedRouteSnapshot({});
    	const state = fakeRouterStateSnapshot({});
    
    	(
    		Object.getOwnPropertyDescriptor(authServiceSpy, 'user$')?.get as any
    	).and?.returnValue(observableData(null));
    
    	guard.canActivate(route, state).subscribe({
    		next: (value) => {
            		expect(value).toBeTrue();
    		},
    	});
    }));
    

Les dejo la documentación de Jasmine por si les interesa profundizar más. Espiando propiedades