Menu

Angular Testing Framework + Como probar un modelo

testingdemos - September 18, 2018 por Carlos Rojas
Angular CLI6.1.1karma1.7.1karma-jasmine1.1.2

Escribir pruebas unitarias nos ayudará a reducir de forma significativa los errores que puedan llegar a producción, en este articulo vamos a ver como empezar a utilizar el conjunto de herramientas que Angular nos provee para realizar pruebas.

Angular Testing Framework.

Desde la versión de Angular 2 en adelante Angular provee un conjunto de herramientas para poder preparar las pruebas unitarias y de esta manera podemos escribir pruebas fácilmente para los artefactos de Angular / Ionic, como componentes, directivas, pipes, providers etc.

Cuando iniciamos un proyecto con Angular CLI al momento de crear el proyecto con ng new nombre-proyecto, nos entrega un proyecto ya preparado para ejecutar y escribir pruebas unitarias con Karma y Jasmine.

¿ Que es Karma ?

Karma es el encargado de correr todas las pruebas unitarias que escribamos y como resultado nos da un reporte que nos muestra las pruebas que pasaron y las pruebas que fallaron. En la mayoría de veces para ejecutar las pruebas unitarias lanza un navegador para correr las pruebas unitarias. Ver mas aquí

¿ Que es Jasmine ?

Jasmine es un framework que nos ayudará a escribir pruebas unitarias y se integra fácilmente con Angular.

Jasmine tiene varias herramientas que nos ayuda a escribir nuestras pruebas unitarias. Y vamos a ver las características más importantes, escribiendo pruebas para este modelo:

$ng g class models/person.model.ts

src/models/person.model.ts

export class Person {
    protected _name: string;
    protected _lastName: string;
    protected _id: number;

    constructor(data: any) {
        if (data.hasOwnProperty('name')) {
            this._name = data.name;
        }
        if (data.hasOwnProperty('lastName')) {
            this._lastName = data.lastName;
        }
        if (data.hasOwnProperty('id')) {
            this._id = data.id;
        }
    }

    get name(): string {
        return this._name;
    }

    get lastName(): string {
        return this._lastName;
    }

    get id(): number {
        return this._id;
    }
}

Vamos a usar a la clase Person y sobre este modelo vamos a escribir pruebas unitarias con Jasmine, revisemos un poco este modelo:

  • Tiene con constructor que recibe un objeto.
  • Tiene varios get que nos devolvera los valores de cada atributo.

Ahora vamos a ponernos manos a la obra y ver las partes clave sobre Jasmine:

Describe:

La sentencia describe se usa para poder agrupar un conjunto de pruebas, donde podemos escribir pruebas unitarias a una clase y luego agrupar pruebas por cada método de la clase así:

describe("Test for Person", ()=>{

  describe("Test for Person with data", ()=>{
  });

  describe("Test for Person without data", ()=>{
  })
})

It

La sentencia it, define cada uno de los casos de prueba que vamos escribir y estarán dentro de cada describe. Cada uno de los it debe evaluar un caso de prueba en particular. Por ejemplo:

src/models/person.model.spec.ts

describe("Test for Person", ()=>{
  
  describe("Test for Person with data", ()=>{

   it("should be defined", ()=>{	
    //CODE
   })
  })
  
  describe("Test for Person without data", ()=>{

    it("shouldn't be defined", ()=>{
		 //CODE
    })
  })
})

BeforeEach:

La sentencia beforeEach la podemos usar para no repetir código, todo lo que este dentro de la sentencia beforeEach se ejecuta por cada describe

describe("Test for Person", ()=>{

  beforeEach(()=>{
   //code for each it
  })

  describe("Test for Person with data", ()=>{
  })
  
  describe("Test for Person without data", ()=>{
  })
})

Expect

La sentencia expect nos sirve para verificar cualquier comportamiento de nuestro código con lo que esperamos como resultado, por ejemplo:

expect(6+6).toEqual(12)
expect(1 === 1).toBeThuthy()
expect(null).toBeNull()
expect("Test").toEqual("Test")

Si miramos cada uno de los ejemplos estamos usando algunos verificadores de Jasmine en donde podemos verificar una variable contra una de las utilidades de Jasmine. Jasmine tiene varios muy útiles, puedes encontrarlos todos en la documentación oficial aquí.

Ahora podemos seguir con nuestro ejemplo y escribir cada unas de las verificaciones:

src/models/person.model.spec.ts

import { Person } from './person.model';

describe('Test for person', () => {

    describe('Test for Person with data', () => {
        it('should be defined', () => {
            const person = new Person({name: 'Jhon', lastName: 'Doe', id: 24});
            expect(person).toBeDefined();
            expect(person.name).toEqual('Jhon');
            expect(person.lastName).toEqual('Doe');
            expect(person.id).toEqual(24);
        });
    });

    describe('Test for Person without data', () => {
        it('should not be defined', () => {
            const person = new Person({});
            expect(person).toBeDefined();
            expect(person.name).toBeUndefined();
            expect(person.lastName).toBeUndefined();
            expect(person.id).toBeUndefined();
        });
    });
});

Ahora vamos a correr nuestras pruebas pruebas con el comando ng test en la terminal y miremos el reporte que nos genera:

Podemos ver que ahora las nuevas pruebas que hemos agregado pasan correctamente con los valores esperados y nos aseguran que en una futura refactorización no vayamos a quebrar nada.

Esto es todo, hasta un proximo post :)

Ver código

Recuerda:

Si quieres ejecutar este demo en tu computadora, debes tener el entorno de ionic instalado y luego de descargar o clonar el proyecto debes ubicarte en tu proyecto en la terminal y luego ejecutar

npm install

esto es para descargar todas las dependencias del proyecto.

¡Compártelo!