Escribiendo Tests para funciones y Propiedades Privadas en Angular
Feb 23, 2022

Escribiendo Tests para funciones y Propiedades Privadas en Angular

🎯 Escribiendo Tests para funciones y Propiedades Privadas en Angular 🅰️✅

Vamos a suponer que ya sabes qué es Angular y cómo crear un servicio en Angular. Cuando ejecutas el comando ng generate service <nombre del servicio>, se crean dos archivos: el archivo del servicio y uno con la extensión .spec. El propósito de este último es proporcionarte una estructura fácil y comprensible para escribir pruebas.

📚 Fundamentos

Supongamos que decides crear un servicio llamado "names" para devolver una lista de nombres. Guardarás los nombres en una propiedad privada y crearás un método get para devolverlos a un controlador u otro servicio. Sería algo así:

// Importa el decorador 'Injectable' de '@angular/core' para definir un servicio inyectable en Angular
import { Injectable } from '@angular/core';

// Aplica el decorador 'Injectable' al servicio y especifica que estará disponible en toda la aplicación ('root')
@Injectable({
    providedIn: 'root'
})
// Exporta la clase 'NamesService' como un servicio inyectable de Angular
export class NamesService {
    // Define una propiedad privada 'names' que es un arreglo de cadenas con dos nombres iniciales
    private names: string[] = ['Juan', 'Mati'];

    // Constructor vacío para la clase 'NamesService'
    constructor() { }

    // Método público 'getNames' que devuelve el arreglo de nombres
    public getNames() {
        return this.names;
    }
}

En nuestra prueba unitaria, podrías intentar algo como esto:

// Importa 'TestBed' e 'inject' de '@angular/core/testing' para crear un entorno de pruebas y hacer pruebas de inyección de dependencias
import { TestBed, inject } from '@angular/core/testing';

// Importa la clase 'NamesService' del archivo 'names.service'
import { NamesService } from './names.service';

// Describe un conjunto de pruebas para 'NamesService'
describe('NamesService', () => {
    // Antes de cada prueba, configura el entorno de pruebas con el módulo de 'NamesService'
    beforeEach(() => {
        TestBed.configureTestingModule({
            providers: [NamesService]
        });
    });

    // Prueba que verifica si el servicio 'NamesService' se crea correctamente
    it('should be created', inject([NamesService], (service: NamesService) => {
        // Espera que el servicio sea verdadero (instanciado)
        expect(service).toBeTruthy();
    }));

    // Prueba que verifica si el método 'getNames' del servicio 'NamesService' devuelve todos los nombres
    it('should return all names', inject([NamesService], (service: NamesService) => {
        // Espera que el resultado de 'getNames()' sea igual al arreglo de nombres 'names'
        expect(service.getNames()).toBe(service.names);
        // Espera que el primer elemento del resultado de 'getNames()' sea igual al primer elemento del arreglo de nombres 'names'
        expect(service.getNames()[0]).toBe(service.names[0]);
        // Espera que el primer elemento del resultado de 'getNames()' sea igual a 'Mati'
        expect(service.getNames()[0]).toBe('Mati');
    }));
});

Sin embargo, no puedes acceder a la propiedad names del servicio porque es privada. 💔 Tu test debería fallar. Para evitar esto, puedes omitir TypeScript y acceder al objeto mediante la sintaxis de array, como service["names"]. Mira cómo quedaría:

// Importa 'TestBed' e 'inject' de '@angular/core/testing' para crear un entorno de pruebas y hacer pruebas de inyección de dependencias
import { TestBed, inject } from "@angular/core/testing";

// Importa la clase 'NamesService' del archivo 'names.service'
import { NamesService } from "./names.service";

// Describe un conjunto de pruebas para 'NamesService'
describe("NamesService", () => {
  // Antes de cada prueba, configura el entorno de pruebas con el módulo de 'NamesService'
  beforeEach(() => {
    TestBed.configureTestingModule({
      providers: [NamesService],
    });
  });

  // Prueba que verifica si el servicio 'NamesService' se crea correctamente
  it("should be created", inject([NamesService], (service: NamesService) => {
    // Espera que el servicio sea verdadero (instanciado)
    expect(service).toBeTruthy();
  }));

  // Prueba que verifica si el método 'getNames' del servicio 'NamesService' devuelve todos los nombres
  it("should return all names", inject(
    [NamesService],
    (service: NamesService) => {
      // Espera que la longitud del resultado de 'getNames()' sea igual a la longitud del arreglo de nombres 'names'
      expect(service.getNames().length).toBe(service["names"].length);
      // Espera que el primer elemento del resultado de 'getNames()' sea igual al primer elemento del arreglo de nombres 'names'
      expect(service.getNames()[0]).toBe(service["names"][0]);
    }
  ));
});

Hay discusiones sobre si es correcto probar propiedades privadas y si esta sintaxis es apropiada. La respuesta dependerá de la filosofía del equipo y la guía de estilo que adopten. Es útil tener una "navaja suiza" de opciones para diferentes casos y proyectos. 🛠️

📝 Conclusiones
  1. Es posible acceder a propiedades privadas en pruebas unitarias utilizando la sintaxis de array en JavaScript.
  2. El enfoque utilizado puede depender de la filosofía del equipo y la guía de estilo.
  3. Tener diferentes opciones de prueba es útil para adaptarse a distintos casos y proyectos.
💡 Ejercicios propuestos
  1. Crea un servicio en Angular que maneje una lista de objetos en lugar de una lista de nombres y adapta las pruebas unitarias para probar las propiedades y métodos privados.
  2. Escribe un conjunto de pruebas unitarias que verifique que se puedan agregar y eliminar elementos de la lista de objetos en el servicio, así como probar las propiedades privadas
  3. Investiga y compara diferentes enfoques para probar propiedades y métodos privados en Angular y discute con tu equipo cuál es el más apropiado para sus proyectos.
📚 Resumen de 3 puntos clave
  1. Utilizar la sintaxis de array en JavaScript para acceder a propiedades privadas en pruebas unitarias de Angular.
  2. Elegir el enfoque de prueba adecuado según la filosofía del equipo y la guía de estilo.
  3. La importancia de tener diferentes opciones de prueba para adaptarse a distintos casos y tipos de proyectos.

¡Eso es todo! Espero que este post te sea de utilidad. Si tienes alguna duda, no dudes en dejarme un comentario en la parte de abajo. Recuerda que si te gustó, también puedes compartir usando los enlaces a las redes sociales en la parte inferior. 🚀🌐

Sebastian Gomez

Sebastian Gomez

Creador de contenido principalmente acerca de tecnología.

Leave a Reply

0 Comments

Related Posts

Categorias