Dev (Back & Front)ARTIGO

Angular 5: criando testes com Jasmine

No seguinte artigo, o autor mostra como é simples a implementação de um teste em um projeto Angular.

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!

Microsoft (MVP), atualmente trabalha como Arquiteto de Software para TV Bandeirantes. Nesses últimos anos, focou nas tecnologias criadas pela Microsoft, mas sempre esteve antenado para as novas tecnologias que estão surgindo no mercado. Em um breve resumo, é uma pessoa apaixonada pelo que faz, tem a sua profissão como hobby.

Ver perfil