Prueba de componentes en Angular usando jazmín Parte 1

Lo que vas a crear

Test Driven Development es una práctica de programación que ha sido predicada y promovida por cada comunidad de desarrolladores en el planeta. Y, sin embargo, es una rutina que un desarrollador descuida en gran medida mientras aprende un nuevo marco. Escribir pruebas unitarias desde el primer día le ayudará a escribir mejor código, detectar errores con facilidad y mantener un mejor flujo de trabajo de desarrollo.

Desarrollo dirigido por pruebas en Angular

Angular, al ser una plataforma de desarrollo de front-end de pleno derecho, tiene su propio conjunto de herramientas para pruebas. Usaremos las siguientes herramientas en este tutorial:

  • Marco de jazmín. Jasmine es un popular marco de pruebas basado en el comportamiento para JavaScript. Con Jasmine, puedes escribir pruebas que sean más expresivas y directas. Aquí hay un ejemplo para empezar.. 
 it ('debería tener un componente definido', () => expect (component) .toBeDefined (););
  • Karma Test Runner. Karma es una herramienta que te permite probar tu aplicación en múltiples navegadores. Karma tiene complementos para navegadores como Chrome, Firefox, Safari y muchos otros. Pero prefiero usar un navegador sin cabeza para las pruebas. Un navegador sin cabeza carece de una GUI, y de esa manera, puede mantener los resultados de las pruebas dentro de su terminal. En este tutorial, configuraremos Karma para ejecutarse con Chrome y, opcionalmente, una versión sin cabeza de Chrome.
  • Utilidades de prueba angular. Las utilidades de prueba angular le proporcionan una biblioteca para crear un entorno de prueba para su aplicación. Clases como TestBed y ComponentFixtures y funciones de ayuda tales como asíncrono y falso async son parte de la @ angular / core / testing paquete. Es necesario familiarizarse con estas utilidades si desea escribir pruebas que revelen cómo sus componentes interactúan con su propia plantilla, servicios y otros componentes..

No vamos a cubrir las pruebas funcionales usando Protractor en este tutorial. Protractor es un popular marco de prueba de extremo a extremo que interactúa con la interfaz de usuario de la aplicación mediante un navegador real. 

En este tutorial, estamos más preocupados por probar los componentes y la lógica del componente. Sin embargo, vamos a escribir un par de pruebas que demuestran la interacción básica de la interfaz de usuario utilizando el marco Jasmine..

Nuestra meta

El objetivo de este tutorial es crear el front-end para una aplicación Pastebin en un entorno de desarrollo basado en pruebas. En este tutorial, seguiremos el popular mantra TDD, que es "rojo / verde / refactor". Escribiremos pruebas que inicialmente fallan (rojo) y luego trabajaremos en nuestro código de aplicación para hacerlas aprobar (verde). Refactorizaremos nuestro código cuando empiece a apestar, lo que significa que se hinchará y se pondrá feo..  

Escribiremos pruebas para los componentes, sus plantillas, servicios y la clase Pastebin. La imagen de abajo ilustra la estructura de nuestra aplicación Pastebin. Los elementos que están en gris se tratarán en la segunda parte del tutorial.. 

En la primera parte de la serie, nos concentraremos únicamente en configurar el entorno de prueba y escribir pruebas básicas para componentes. Angular es un marco basado en componentes; por lo tanto, es una buena idea dedicar algún tiempo a familiarizarse con las pruebas de escritura de los componentes. En la segunda parte de la serie, escribiremos pruebas más complejas para componentes, componentes con entradas, componentes enrutados y servicios. Al final de la serie, tendremos una aplicación Pastebin totalmente funcional que se verá así..

Vista del componente Pastebin.Vista del componente AddPaste
Vista del componente ViewPaste

En este tutorial, aprenderás cómo:

  • configurar jazmín y karma
  • crear una clase de Pastebin que representa una pasta individual
  • crear un PastebinService básico 
  • Crea dos componentes, Pastebin y AddPaste
  • escribir pruebas unitarias

El código completo para el tutorial está disponible en Github. 

https://github.com/blizzerand/pastebin-angular

Clone el repositorio y siéntase libre de revisar el código si tiene dudas en alguna etapa de este tutorial. Empecemos!

Configurando Jasmine y Karma

Los desarrolladores de Angular nos han facilitado la configuración de nuestro entorno de prueba. Para empezar, necesitamos instalar Angular primero. Prefiero usar el Angular-CLI. Es una solución todo en uno que se encarga de crear, generar, construir y probar su proyecto Angular..

ng nuevo Pastebin

Aquí está la estructura del directorio creado por Angular-CLI. 

Dado que nuestros intereses se inclinan más hacia los aspectos de prueba en Angular, debemos tener en cuenta dos tipos de archivos.

karma.conf.js es el archivo de configuración para el corredor de prueba Karma y el único archivo de configuración que necesitaremos para escribir pruebas unitarias en Angular. De forma predeterminada, Chrome es el iniciador de navegador predeterminado utilizado por Karma para capturar pruebas. Crearemos un lanzador personalizado para ejecutar el Chrome sin cabeza y lo agregaremos a la navegadores formación.

/*karma.conf.js*/ browsers: ['Chrome', 'ChromeNoSandboxHeadless'], customLaunchers: ChromeNoSandboxHeadless: base: 'Chrome', flags: ['--no-sandbox', // See https: / /chromium.googlesource.com/chromium/src/+/lkgr/headless/README.md '--headless', '--disable-gpu', // Sin un puerto de depuración remoto, Google Chrome se cierra de inmediato. '--remote-debugging-port = 9222',],,,

El otro tipo de archivo que debemos buscar es cualquier cosa que termine con .espec.ts. Por convención, las pruebas escritas en Jasmine se llaman especificaciones. Todas las especificaciones de prueba deben estar ubicadas dentro de la aplicación src / app / directorio porque ahí es donde Karma busca las especificaciones de prueba. Si crea un nuevo componente o un servicio, es importante que coloque sus especificaciones de prueba dentro del mismo directorio en el que reside el código del componente o servicio.. 

los ng nuevo comando ha creado un app.component.spec.ts archivo para nuestro app.component.ts. Siéntase libre de abrirlo y echar un buen vistazo a las pruebas de jazmín en Angular. Incluso si el código no tiene ningún sentido, está bien. Mantendremos AppComponent como está por ahora y lo utilizaremos para alojar las rutas en algún momento posterior del tutorial.. 

Creando la clase Pastebin

Necesitamos una clase de Pastebin para modelar nuestro Pastebin dentro de los componentes y pruebas. Puedes crear uno usando el Angular-CLI.

ng generar clase Pastebin

Agregue la siguiente lógica a Pastebin.ts:

clase de exportación Pastebin id: número; título: cadena; lenguaje: cadena; pegar: cuerda; constructor (valores: Object = ) Object.assign (this, valores);  export const Languages ​​= ["Ruby", "Java", "JavaScript", "C", "Cpp"]; 

Hemos definido una clase Pastebin y cada instancia de esta clase tendrá las siguientes propiedades:

  • carné de identidad 
  • título
  • idioma
  • pegar

Crea otro archivo llamado pastebin.spec.ts para la suite de pruebas. 

/ * pastebin.spec.ts * / // importa la clase de Pastebin import Pastebin de './pastebin'; describe ('Pastebin', () => it ('debería crear una instancia de Pastebin', () => expect (new Pastebin ()). toBeTruthy (););)

El conjunto de pruebas comienza con un describir bloque, que es una función global de Jasmine que acepta dos parámetros. El primer parámetro es el título del conjunto de pruebas y el segundo es su implementación real. Las especificaciones se definen utilizando un eso Función que toma dos parámetros, similar a la de la describir bloquear. 

Especificaciones múltiples (eso bloques) se pueden anidar dentro de un conjunto de pruebas (describir bloquear). Sin embargo, asegúrese de que los títulos de la suite de pruebas se nombren de tal manera que sean inequívocos y más legibles porque están destinados a servir como documentación para el lector.. 

Expectativas, implementadas utilizando el esperar función, son utilizados por Jasmine para determinar si una especificación debe pasar o fallar. los esperar La función toma un parámetro que se conoce como el valor real. Luego se encadena con otra función que toma el valor esperado. Estas funciones se denominan funciones de comparación y utilizaremos las funciones de comparación como toBeTruthy ()toBeDefined ()ser(), y contener() mucho en este tutorial. 

 expect (new Pastebin ()). toBeTruthy ();

Entonces, con este código, hemos creado una nueva instancia de la clase Pastebin y esperamos que sea verdadera. Agreguemos otra especificación para confirmar que el modelo de Pastebin funciona según lo previsto.. 

it ('debería aceptar valores', () => let pastebin = new Pastebin (); pastebin = id: 111, título: "Hello world", idioma: "Ruby", pegar: 'print "Hello"',  expect (pastebin.id) .toEqual (111); expect (pastebin.language) .toEqual ("Ruby"); expect (pastebin.paste) .toEqual ('print "Hello"');); 

Hemos creado una instancia de la clase Pastebin y hemos agregado algunas expectativas a nuestra especificación de prueba. correr prueba de ng para verificar que todas las pruebas sean verdes.

Creando un Servicio Bare-Bones

Genera un servicio usando el siguiente comando.

ng generar servicio pastebin

Servicio de Pastebin alojará la lógica para enviar solicitudes HTTP al servidor; sin embargo, no tenemos una API de servidor para la aplicación que estamos creando. Por lo tanto, vamos a simular la comunicación del servidor utilizando un módulo conocido como InMemoryWebApiModule. 

Configuración de la API web de memoria angular

Instalar api-en-memoria-web-api a través de npm:

npm instala angular-in-memory-web-api --save

Actualizar AppModule con esta versión.

/ * app.module.ts * / import BrowserModule de '@ angular / platform-browser'; importe NgModule desde '@ angular / core'; // Los componentes importan AppComponent de './app.component'; // Servicio para la importación de Pastebin PastebinService de "./pastebin.service"; // Los módulos utilizados en este tutorial importan HttpModule de '@ angular / http'; // En la memoria web api para simular una importación del servidor http InMemoryWebApiModule desde 'angular-in-memory-web-api'; importar InMemoryDataService desde './in-memory-data.service'; @NgModule (declaraciones: [AppComponent,], importa: [BrowserModule, HttpModule, InMemoryWebApiModule.forRoot (InMemoryDataService),], proveedores: [PastebinService], bootstrap: [AppComponent]) clase de exportación AppModule 

Crear un InMemoryDataService que implementa InMemoryDbService

/*in-memory-data.service.ts*/ import InMemoryDbService de 'angular-in-memory-web-api'; importar Pastebin desde './pastebin'; export class InMemoryDataService implementa InMemoryDbService createDb () const pastebin: Pastebin [] = [id: 0, título: "Hello world Ruby", idioma: "Ruby", paste: 'pone "Hello World"', id : 1, título: "Hola mundo C", idioma: "C", pegar: 'printf ("Hola mundo");', id: 2, título: "Hola mundo CPP", idioma: "C ++", pegar: 'cout<<"Hello world";', id: 3, title: "Hello world Javascript", language: "JavaScript", paste: 'console.log("Hello world")' ]; return pastebin;  

aquí, pastebin es una matriz de pastas de muestra que se devolverá o actualizará cuando realicemos una acción HTTP como http.get o http.post.  

/*pastebin.service.ts * / import Injectable de '@ angular / core'; importar Pastebin desde './pastebin'; importar Http, Headers desde '@ angular / http'; importar 'rxjs / add / operator / toPromise'; @Injectable () exportar clase PastebinService // El proyecto usa InMemoryWebApi para manejar la API del servidor. // Aquí "api / pastebin" simula un URL de la API del servidor, pastebinUrl = "api / pastebin"; encabezados privados = nuevos encabezados ('Content-Type': "application / json"); constructor (privado http: Http)  // getPastebin () realiza http.get () y devuelve una promesa pública getPastebin (): Promise return this.http.get (this.pastebinUrl) .toPromise () .then (response => response.json (). data) .catch (this.handleError);  private handleError (error: cualquiera): Promesa console.error ('Ocurrió un error', error); devolver Promise.reject (error.message || error); 

los getPastebin () El método realiza una solicitud HTTP.get y devuelve una promesa que se resuelve en una matriz de objetos Pastebin devueltos por el servidor.

Si obtienes un Ningún proveedor para HTTP error mientras ejecuta una especificación, debe importar el módulo HTTP al archivo de especificación correspondiente. 

Primeros pasos con los componentes

Los componentes son el bloque de construcción más básico de una interfaz de usuario en una aplicación angular. Una aplicación angular es un árbol de componentes angulares.. 
- Documentacion angular

Como se destacó anteriormente en la sección Información general, trabajaremos en dos componentes en este tutorial: PastebinComponent y AddPasteComponent. El componente Pastebin consta de una estructura de tabla que enumera toda la pasta recuperada del servidor. El componente AddPaste mantiene la lógica para la creación de nuevas pastas.   

Diseñar y probar el componente Pastebin

Continúe y genere los componentes utilizando Angular-CLI.. 

ng g componente --spec = falso Pastebin

los --spec = falso La opción le dice a Angular-CLI que no cree un archivo de especificaciones. Esto se debe a que queremos escribir pruebas unitarias para componentes desde cero. Crear un pastebin.component.spec.ts archivo dentro de la componente de pastebin carpeta.

Aquí está el código para pastebin.component.spec.ts.

importe TestBed, ComponentFixture, async desde '@ angular / core / testing'; importe DebugElement desde '@ angular / core'; importe PastebinComponent desde './pastebin.component'; importar By desde '@ angular / platform-browser'; importe Pastebin, Idiomas desde '… / pastebin'; // Los módulos utilizados para probar la importación HttpModule de '@ angular / http'; describe ('PastebinComponent', () => // Declaraciones de manuscritos. let comp: PastebinComponent; let fixture: ComponentFixture; let de: DebugElement; dejar elemento: HTMLElement; Deje mockPaste: Pastebin []; // beforeEach se llama una vez antes de cada bloque 'it' en una prueba. // Use esto para configurar el componente, inyectar servicios, etc. antes de Cada (() => TestBed.configureTestingModule (declaraciones: [PastebinComponent], // declarar las importaciones del componente de prueba: [HttpModule],); fixture = TestBed .createComponent (PastebinComponent); comp = fixture.componentInstance; de ​​= fixture.debugElement.query (By.css ('. pastebin')); element = de.nativeElement;); )

Hay mucho que hacer aquí. Vamos a romper y tomar una pieza a la vez. Dentro de describir bloque, hemos declarado algunas variables, y luego hemos utilizado una antes de cada función. antes de cada () es una función global proporcionada por Jasmine y, como su nombre indica, se invoca una vez antes de cada especificación en el describir Bloque en el que se llama.. 

TestBed.configureTestingModule (declaraciones: [PastebinComponent], // declara las importaciones del componente de prueba: [HttpModule],);

TestBed clase es una parte de las utilidades de prueba Angular, y crea un módulo de prueba similar al de la @NgModule clase. Además, puede configurar TestBed utilizando la configureTestingModule método. Por ejemplo, puede crear un entorno de prueba para su proyecto que emule la aplicación Angular real, y luego puede extraer un componente de su módulo de aplicación y volver a adjuntarlo a este módulo de prueba.. 


fixture = TestBed.createComponent (PastebinComponent); comp = fixture.componentInstance; de = fixture.debugElement.query (By.css ('div')); elemento = de.nativeElement;

De la documentación angular:

los createComponent método devuelve un ComponentFixture, un controlador en el entorno de prueba que rodea el componente creado. El dispositivo proporciona acceso a la instancia del componente en sí y a la Depuración de elementos, que es un controlador en el elemento DOM del componente.

Como se mencionó anteriormente, hemos creado un accesorio de la PastebinComponent y luego usó ese accesorio para crear una instancia del componente. Ahora podemos acceder a las propiedades y métodos del componente dentro de nuestras pruebas llamando al comp.property_name. Dado que el accesorio también proporciona acceso a la depuración de elementos, Ahora podemos consultar los elementos y selectores de DOM.. 

Hay un problema con nuestro código que aún no hemos pensado. Nuestro componente tiene una plantilla externa y un archivo CSS. Recuperarlos y leerlos del sistema de archivos es una actividad asíncrona, a diferencia del resto del código, que es todo síncrono.. 

Angular te ofrece una función llamada asíncrono () Eso se encarga de todo lo asíncrono. Lo que hace async es hacer un seguimiento de todas las tareas asíncronas en su interior, mientras nos oculta la complejidad de la ejecución asíncrona. Así que ahora tendremos dos funciones beforeEach, una asincrónica antes de cada () y un síncrono antes de cada ().

/ * pastebin.component.spec.ts * / // beforeEach se llama una vez antes de cada bloque 'it' en una prueba. // Use esto para configurar el componente, inyectar servicios, etc. BeforeEach (async (() => // async before se usa para compilar plantillas externas que es cualquier actividad async TestBed.configureTestingModule (declaraciones: [PastebinComponent], / / declara las importaciones del componente de prueba: [HttpModule],) .compileComponents (); // compile template and css)); beforeEach (() => // Y aquí está la función asíncrona síncrona fixture = TestBed.createComponent (PastebinComponent); comp = fixture.componentInstance; de ​​= fixture.debugElement.query (By.css ('. pastebin')); element = de.nativeElement;); 

No hemos escrito ninguna especificación de prueba todavía. Sin embargo, es una buena idea crear un esquema de las especificaciones de antemano. La imagen de abajo muestra un diseño aproximado del componente Pastebin..

Necesitamos escribir tests con las siguientes expectativas..

  • El componente Pastebin debe existir.
  • La propiedad del título del componente debe mostrarse en la plantilla.
  • La plantilla debe tener una tabla HTML para mostrar las pastas existentes.
  • pastebinService Se inyecta en el componente, y sus métodos son accesibles..
  • No se deben mostrar pastas hasta onInit () se llama.
  • Las pastas no se muestran hasta después de que se resuelva la promesa en nuestro Servicio.

Las primeras tres pruebas son fáciles de implementar. 

 it ('debería tener un Componente', () => expect (comp) .toBeTruthy ();); it ('debería tener un título', () => comp.title = 'Pastebin Application'; fixture.detectChanges (); expect (element.textContent) .toContain (comp.title);) it ('debería tener una tabla para mostrar las pastas ', () => expect (element.innerHTML) .toContain ("thead"); expect (element.innerHTML) .toContain ("tbody");) 

En un entorno de prueba, Angular no vincula automáticamente las propiedades del componente con los elementos de la plantilla. Tienes que llamar explícitamente fixture.detectChanges () Cada vez que quiera enlazar una propiedad de componente con la plantilla. La ejecución de la prueba debería darle un error porque aún no hemos declarado la propiedad del título dentro de nuestro componente.

 title: string = "Aplicación Pastebin";

No olvides actualizar la plantilla con una estructura de tabla básica..

título

carné de identidad Título Idioma Código

En cuanto al resto de los casos, necesitamos inyectar el Pastebinservice y escribir pruebas que traten la interacción componente-servicio. Un servicio real puede hacer llamadas a un servidor remoto, e inyectarlo en su forma original será una tarea laboriosa y desafiante. 

En su lugar, deberíamos escribir pruebas que se centren en si el componente interactúa con el servicio como se espera. Añadiremos especificaciones que espíen al pastebinService y es getPastebin () método.

Primero, importa el Servicio de Pastebin en nuestra suite de prueba.

importe PastebinService desde '… /pastebin.service';

A continuación, agréguelo a la proveedores matriz dentro TestBed.configureTestingModule ().

TestBed.configureTestingModule (declaraciones: [CreateSnippetComponent], proveedores: [PastebinService],);

El siguiente código crea un espía Jasmine que está diseñado para rastrear todas las llamadas al getPastebin () Método y devolver una promesa que resuelve inmediatamente mockPaste.

// El PastebinService real se inyecta en el componente let pastebinService = fixture.debugElement.injector.get (PastebinService); mockPaste = [id: 1, título: "Hola mundo", idioma: "Ruby", pega: "pone 'Hola'"]; spy = spyOn (pastebinService, 'getPastebin') .and.returnValue (Promise.resolve (mockPaste));

Al espía no le preocupan los detalles de la implementación del servicio real, sino que, por el contrario, elude cualquier llamada al servicio real. getPastebin () método. Además, todas las llamadas remotas enterradas en el interior. getPastebin () Son ignorados por nuestras pruebas. Escribiremos pruebas unitarias aisladas para servicios angulares en la segunda parte del tutorial..

Agregue las siguientes pruebas a pastebin.component.spec.ts.

 it ('no debería mostrar el pastebin antes de OnInit', () => this.tbody = element.querySelector ("tbody"); // Intente esto sin el método 'replace (\ s \ s + / g, ")' y vea qué sucede expect (this.tbody.innerText.replace (/ \ s \ s + / g, ")). toBe (" "," tbody debe estar vacío "); expect (spy.calls.any ()). toBe (falso, "El espía aún no debe ser llamado");); it ('aún no debería mostrar pastebin después de que se inicializó el componente', () => fixture.detectChanges (); // el servicio getPastebin es asíncrono, pero la prueba no es. expect (this.tbody.innerText.replace (/ \ s \ s + / g, ")). toBe (" ", 'el cuerpo todavía debe estar vacío'); expect (spy.calls.any ()). toBe (true, 'getPastebin debe llamarse');); ('debería mostrar el pastebin después de que se resuelva la promesa de getPastebin', async () => fixture.detectChanges (); fixture.whenStable (). then (() => fixture.detectChanges (); expect (comp.pastebin). toEqual (jasmine.objectContaining (mockPaste)); expect (element.innerText.replace (/ \ s \ s + / g, ")) .ConContain (mockPaste [0] .title););)

Las dos primeras pruebas son pruebas síncronas. La primera especificación verifica si el texto interior del div el elemento permanece vacío siempre que el componente no esté inicializado. El segundo argumento de la función de comparación de Jasmine es opcional y se muestra cuando falla la prueba. Esto es útil cuando tiene varias declaraciones de expectativa dentro de una especificación.

En la segunda especificación, el componente se inicializa (porque fixture.detectChanges () se llama), y también se espera que el espía sea invocado, pero la plantilla no debe actualizarse. A pesar de que el espía devuelve una promesa resuelta, el mockPaste no está disponible todavía. No debería estar disponible a menos que la prueba sea una prueba asíncrona..

La tercera prueba utiliza un asíncrono () Función analizada anteriormente para ejecutar la prueba en una zona de prueba asíncrona. asíncrono () Se utiliza para hacer una prueba síncrona asíncrona.. fixture.whenStable () se llama cuando todas las actividades asíncronas pendientes se complementan, y luego una segunda ronda de fixture.detectChanges () Se llama a actualizar el DOM con los nuevos valores. La expectativa en la prueba final asegura que nuestro DOM se actualice con el mockPaste valores.

Para que las pruebas pasen, necesitamos actualizar nuestra pastebin.component.ts con el siguiente código.

/*pastebin.component.ts*/ import Component, OnInit de '@ angular / core'; importa Pastebin desde '… / pastebin'; importe PastebinService desde '… /pastebin.service'; @Component (selector: 'app-pastebin', templateUrl: './pastebin.component.html', styleUrls: ['./pastebin.component.css']) clase de exportación PastebinComponent implementa OnInit title: string = " Aplicación Pastebin "; pastebin: cualquiera = []; se llama al constructor (public pastebinServ: PastebinService)  // loadPastebin () en init ngOnInit () this.loadPastebin ();  public loadPastebin () // invoca el método getPastebin () del servicio pastebin y almacena la respuesta en la propiedad 'pastebin' this.pastebinServ.getPastebin (). then (pastebin => this.pastebin = pastebin);  

La plantilla también necesita ser actualizada.

 

título

carné de identidad Título Idioma Código
paste.id paste.title paste.language Ver codigo

Añadiendo una nueva pasta

Genere un componente AddPaste usando Angular-CLI. La imagen de abajo muestra el diseño del componente AddPaste.


La lógica del componente debe pasar las siguientes especificaciones.

  • La plantilla del componente AddPaste debe tener un botón llamado Crear pegar.
  • Haciendo clic en el Crear pegar botón debería mostrar un cuadro modal con id 'fuente-modal'.
  • La acción de clic también debería actualizar el componente showModal propiedad a cierto. (showModal es una propiedad booleana que se vuelve verdadera cuando se muestra el modal y falsa cuando se cierra el modal.)
  • Presionando el salvar botón debe invocar el servicio de Pastebin addPaste () método.
  • Haciendo clic en el cerrar botón debería eliminar el id 'fuente-modal' del DOM y actualizar el showModal propiedad a falso.

Hemos elaborado las tres primeras pruebas para usted. Mira si puedes hacer que las pruebas pasen por tu cuenta.. 

describe ('AddPasteComponent', () => let component: AddPasteComponent; let fixture: ComponentFixture; let de: DebugElement; dejar elemento: HTMLElement; Deja espiar: jazmín.Spy; vamos pastebinService: PastebinService; beforeEach (async (() => TestBed.configureTestingModule (declaraciones: [AddPasteComponent], importa: [HttpModule, FormsModule], proveedores: [PastebinService],) .compileComponents ();)))); beforeEach (() => // initialization fixture = TestBed.createComponent (AddPasteComponent); pastebinService = fixture.debugElement.injector.get (PastebinService); component = fixture.componentInstance; de ​​= fixture.debugElement.query (By.css ( '.add-paste')); element = de.nativeElement; spy = spyOn (pastebinService, 'addPaste'). and.callThrough (); // pide al dispositivo que detecte los cambios fixture.detectChanges ();); it ('debería ser creado', () => expect (component) .toBeTruthy ();); it ('debería mostrar el botón' crear Pegar '', () => // Debe haber un botón crear en la plantilla esperar (element.innerText) .toContain ("create Paste");); it ('no debería mostrar el modal a menos que se haga clic en el botón', () => // source-model es un id para el modal. No se debe mostrar a menos que se haga clic en el botón de espera (element.innerHTML). not.toContain ("source-modal");) it ("debería mostrar el modal cuando se hace clic en 'create Paste'", () => let createPasteButton = fixture.debugElement.query (By.css ("button" )); // triggerEventHandler simula un evento clic en el objeto de botón createPasteButton.triggerEventHandler ("click", null); fixture.detectChanges (); expect (element.innerHTML) .toContain ("source-modal"); expect (component .showModal) .toBeTruthy ("showModal debe ser verdadero");))

DebugElement.triggerEventHandler () Es lo único nuevo aquí. Se utiliza para activar un evento de clic en el elemento de botón en el que se llama. El segundo parámetro es el objeto de evento, y lo hemos dejado vacío ya que los componentes hacer clic() no espera uno. 

Resumen

Eso es todo por el día. En este primer artículo, aprendimos:

  • Cómo configurar y configurar Jasmine y Karma.
  • Cómo escribir exámenes básicos para las clases.
  • Cómo diseñar y escribir pruebas unitarias para componentes.
  • Cómo crear un servicio básico.
  • Cómo utilizar las utilidades de prueba angular en nuestro proyecto.

 En el siguiente tutorial, crearemos nuevos componentes, escribiremos más componentes de prueba con entradas y salidas, servicios y rutas. Estén atentos para la segunda parte de la serie. Comparte tus pensamientos a través de los comentarios..