unit-testing - routertestingmodule - test router navigate angular 6
¿Cómo probar el router.navigate de Angular2? (2)
Podría burlarme del enrutador y hacer mi propia función de navegación, pero ¿cuál es el punto de RouterTestingModule? Quizás incluso quieras comprobar que la navegación funcionó.
No hay un punto real. Si el suyo es solo una prueba de unidad para el guardia de autenticación, entonces solo se burlan y espían en el simulacro para comprobar que se ha llamado al método de navigate
con el argumento de login
let router = {
navigate: jasmine.createSpy(''navigate'')
}
{ provide: Router, useValue: router }
expect(authGuardService.canActivate(<any>{}, <any>{})).toBe(false);
expect(router.navigate).toHaveBeenCalledWith([''/login'']);
Así es como deberían escribirse normalmente las pruebas unitarias . Para intentar probar cualquier navegación real real, eso probablemente caería bajo el paraguas de las pruebas de extremo a extremo.
Me he topado con la falta de mensajes <router-outlet>
en otras pruebas de unidad, pero solo para tener un buen ejemplo aislado, creé un AuthGuard que verifica si un usuario ha iniciado sesión para ciertas acciones.
Este es el código:
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
if (!this.authService.isLoggedIn()) {
this.router.navigate([''/login'']);
return false;
}
return true;
}
Ahora quiero escribir una prueba de unidad para esto.
Así es como empiezo mi prueba:
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
RouterTestingModule.withRoutes([
{
path: ''login'',
component: DummyComponent
}
])
],
declarations: [
DummyComponent
],
providers: [
AuthGuardService,
{
provide: AuthService,
useClass: MockAuthService
}
]
});
});
He creado un DummyComponent que no hace nada. Ahora mi prueba. Pretenda que el servicio devuelve falso y que activa this.router.navigate([''/login''])
:
it(''should not let users pass when not logged in'', (): void => {
expect(authGuardService.canActivate(<any>{}, <any>{})).toBe(false);
});
Esto generará una excepción con "No se puede encontrar la salida principal para cargar". Obviamente puedo usar toThrow()
lugar de toBe(false)
, pero eso no parece ser una solución muy sensata. Como estoy probando un servicio aquí, no hay una plantilla donde pueda colocar la etiqueta <router-outlet>
. Podría burlarme del enrutador y hacer mi propia función de navegación, pero ¿cuál es el punto de RouterTestingModule? Quizás incluso quieras comprobar que la navegación funcionó.
Si desea probar el enrutador sin burlarse de él, puede inyectarlo en su prueba y luego espiar directamente el método de navegación allí. El .and.stub()
lo hará para que la llamada no haga nada.
describe(''something that navigates'', () => {
it(''should navigate'', inject([Router], (router: Router) => {
spyOn(router, ''navigate'').and.stub();
expect(authGuardService.canActivate(<any>{}, <any>{})).toBe(false);
expect(router.navigate).toHaveBeenCalledWith([''/login'']);
}));
});