Desenvolvimento

27 abr, 2018

Angular 5: criando testes com Jasmine

Publicidade

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:

Validando serviço de autenticação

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:

Validando middler AuthGuard

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:

Teste de fluxo de login

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!