Dando continuidade à minha série de artigos sobre Jasmine, hoje irei demonstrar como validar um componente Angular 5 utilizando ele mesmo. Caso tenha interesse em ler o primeiro artigo da série, segue o link:
Para que pularmos a etapa de configuração de um projeto, eu irei partir de um já criado com o Angular Cli. Caso tenha interesse em clonar ele, segue o seu link:
Navegando rapidamente pelo projeto, você tem:
- 4 componentes: Home, About, error e login
- AuthGuard: middler de gerenciamento de rotas, caso tenha interesse em saber um pouco mais sobre esse assunto, eu recomento a leitura do seguinte artigo: Angular 5: Trabalhando com Rotas.
Agora, para que você possa ter um exemplo real, eu irei criar alguns testes abordando o fluxo de autenticação de um usuário. Para isso, execute o seguinte comando no seu terminal:
ng g s services/login
O comando acima criará um arquivo chamado login.service.ts e um outro login.service.spec.ts dentro do diretório services.
Para validar todo processo de autenticação, nós precisaremos criar os seguintes testes:
- Validar se um usuário está logado
- Validar o processo de login
- Validar se o token está armazenado corretamente
Para isso, atualize os arquivos abaixo:
login.service.ts
import { Injectable } from '@angular/core'; @Injectable() export class LoginService { constructor() { } auth(user: string, password: string): boolean { if (user == 'dotnet' && password == 'SP') { localStorage.setItem('token', '.NET_SP'); return true; } else { return false; } } }
Acima eu criei um método que recebe dois parâmetros; um para o usuário, e outro para senha. Esse método validará se os dados de acesso de um usuário X estão corretos e retornará um boolean.
login.service.spec.ts
import { TestBed, inject } from '@angular/core/testing'; import { LoginService } from './login.service'; describe('Validar serviço de autenticação', () => { beforeEach(() => { TestBed.configureTestingModule({ providers: [LoginService] }); }); it('Usuário e senha válidos', inject([LoginService], (service: LoginService) => { expect(service.auth('dotnet', 'SP')).toBeTruthy(); })); it('Usuário ou senha válido(s)', inject([LoginService], (service: LoginService) => { expect(service.auth('dotnet', 'SP2')).toBeFalsy(); })); });
No teste acima, você tem:
- Um teste esperando um retorno true
- Um método passando o usuário correto e a senha errada, esse deve retornar false
Execute o comando npm test no seu terminal para validar esse teste. Note que ele irá abrir uma nova aba no seu navegador demonstrando o status dele. Você pode ver esse passo na imagem abaixo:
O próximo passo será validar o middler AuthGuard. Para isso, atualize o seu arquivo auth.guard.ts com o trecho de código abaixo:
import { Observable } from 'rxjs/Observable'; import { Injectable } from '@angular/core'; import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, Router } from "@angular/router"; @Injectable() export class AuthGuard implements CanActivate { constructor() { } canActivate( route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> | boolean { if (localStorage['token'] != null) { return true; } else { return false; } } }
Agora crie, dentro do diretório auth, um arquivo chamado auth.guard.spec.ts e atualize ele com o seguinte trecho de código:
import { TestBed, inject } from '@angular/core/testing'; import { AuthGuard } from './auth.guard.service'; import { ActivatedRouteSnapshot, RouterStateSnapshot } from "@angular/router/src"; describe('Validando se o usuário está autenticado', () => { let route: ActivatedRouteSnapshot; let state: RouterStateSnapshot; beforeEach(() => { TestBed.configureTestingModule({ providers: [AuthGuard] }); }); afterEach(() => { localStorage.removeItem('token'); }); it('Usuário está autenticado', inject([AuthGuard], (service: AuthGuard) => { localStorage.setItem('token', '.NETSP'); expect(service.canActivate(route, state)).toBeTruthy(); })); it('Usuário não está autenticado', inject([AuthGuard], (service: AuthGuard) => { expect(service.canActivate(route, state)).toBeFalsy(); })); });
Voltando para aba que está rodando o seu teste, você pode notar que já estão aparecendo os novos testes:
Vamos agora ao último teste; verificar se um usuário está logado ou não. Para isso, atualize os arquivos abaixo:
login.component.ts
import { Component, OnInit } from '@angular/core'; import { LoginService } from '../../services/login.service'; @Component({ selector: 'app-login', templateUrl: './login.component.html', styleUrls: ['./login.component.css'] }) export class LoginComponent implements OnInit { constructor(private auth: LoginService) { } ngOnInit() { } LogIn() { return !this.auth.isAuthenticated(); } }
login.component.spec.ts
import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { LoginComponent } from './login.component'; import { LoginService } from '../../services/login.service'; describe('Validação de login', () => { let component: LoginComponent; let service: LoginService; beforeEach(() => { service = new LoginService(); component = new LoginComponent(service); }); afterEach(() => { localStorage.removeItem('token'); service = null; component = null; }); it('Validar se o usuário não está autenticado', () => { localStorage.removeItem('token'); expect(component.LogIn()).toBeFalsy(); }); it('Validar se o usuário está autenticado', () => { localStorage.setItem('token', '.NETSP'); expect(component.LogIn()).toBeTruthy(); }); });
Nesse teste eu estou validando se o token existe. Caso não, o usuário deveria ser direcionado para tela de login. Para verificar se esta tudo ok, volte para a aba que está executando os seus testes e note que todos os testes estão lá. Abaixo, você tem uma imagem demonstrando esse passo:
Bom, o objetivo desse artigo foi demonstrar como é simples a implementação de um teste em um projeto Angular. Eu resolvi criar essa série de artigos para tentar passar um pouco do que eu estou estudando e tentar ajudar o pessoal que está tentando adotar esse passo no dia dia. Espero ter ajudado e até o próximo artigo dessa serie!