
Fixes #230 Co-authored-by: José de Jesús Amaya <impepedev@gmail.com> Co-authored-by: Pato <11162114+devpato@users.noreply.github.com>
8.7 KiB
Probando servicios
Para comprobar que tus servicios funcionan como deseas, puedes escribir pruebas específicamente para ellos.
Para la aplicación de muestra que describe las guías de prueba, consulta la aplicación de muestra.
Para las funcionalidades de las pruebas en las guías de prueba, consulta las pruebas.
Los servicios suelen ser los archivos en los que es mas fácil realizar pruebas unitarias.
Estas son algunas pruebas unitarias sincrónicas y asincrónicas del ValueService
escritas sin ayuda de las utilidades de prueba Angular.
{@a services-with-dependencies}
Servicios con dependencias
Los servicios a menudo dependen de otros servicios que Angular inyecta en el constructor. En muchos casos, es fácil crear e inyectar estas dependencias a mano mientras se llama al constructor del servicio.
El MasterService
es un ejemplo simple:
MasterService
delega su único método, getValue
, al ValueService
inyectado.
Aquí hay varias formas de probarlo.
La primera prueba crea un ValueService
con new
y lo pasa al constructor de MasterService
.
Sin embargo, inyectar el servicio real rara vez funciona bien, ya que la mayoría de los servicios dependientes son difíciles de crear y controlar.
En su lugar, puedes hacer un mock de la dependencia, usar un valor ficticio o crear un espía sobre el método del servicio pertinente.
Utiliza espías, ya que suelen ser la forma más fácil de hacer mocks a los servicios.
Estas técnicas de prueba estándar son excelentes para hacer pruebas unitarias de servicios de forma aislada.
Sin embargo, casi siempre inyecta servicios en clases de aplicación usando la inyección de dependencias de Angular y debe tener pruebas que reflejen ese patrón de uso. Las utilidades de pruebas de Angular facilitan la investigación de cómo se comportan los servicios inyectados.
Probando los servicios con TestBed
Tu aplicación se basa en la inyección de dependencias (ID) de Angular para crear servicios. Cuando un servicio tiene un servicio dependiente, la inyección de dependencia busca o crea ese servicio dependiente. Y si ese servicio dependiente tiene sus propias dependencias, la inyección de dependencia también las encuentra o crea.
Como consumidor de servicios, no te preocupas por nada de esto. No te preocupes por el orden de los argumentos del constructor o cómo se crean.
Como probador de servicios, debes pensar al menos en el primer nivel de dependencias del servicio
pero puedes dejar que la inyección de dependencia de Angular haga la creación del servicio y se ocupe del orden de los argumentos del constructor
cuando uses la utilidad de prueba TestBed
para proporcionar y crear servicios.
{@a testbed}
Angular TestBed
El TestBed
es la más importante de las utilidades de prueba de Angular.
El TestBed
crea un modulo Angular test construido dinámicamente que emula
un @NgModule de Angular.
El método TestBed.configureTestingModule()
toma un objeto de metadatos que puede tener la mayoría de las propiedades de un @NgModule.
Para probar un servicio, estableces la propiedad de metadatos de providers
con un
array de los servicios que probarás o simularás.
Luego inyéctalo dentro de una prueba llamando TestBed.inject()
con la clase del servicio como argumento.
Nota: TestBed.get()
quedó obsoleto a partir de la versión 9 de Angular.
Para ayudar a minimizar los cambios importantes, Angular presenta una nueva función llamada TestBed.inject()
, que deberas usar en su lugar.
Para obtener información sobre la eliminación de TestBed.get()
,
consulta su entrada en el Índice de bajas.
O dentro del beforeEach()
si prefieres inyectar el servicio como parte de tu configuración.
Al probar un servicio con una dependencia, proporcione un mock en el array de providers
.
En el siguiente ejemplo, el mock es un objeto espía.
La prueba consume ese espía de la misma manera que lo hizo antes.
{@a no-before-each}
Pruebas sin beforeEach()
La mayoría de los conjuntos de pruebas en esta guía llaman a beforeEach()
para establecer las condiciones previas para cada prueba it()
y confían en TestBed
para crear clases e inyectar servicios.
Hay otra escuela de pruebas que nunca llama a beforeEach()
y prefiere crear clases explícitamente en lugar de usar el TestBed
.
Así es como podrías reescribir una de las pruebas del MasterService
en ese estilo.
Empieza poniendo código preparatorio reutilizable en una función setup en lugar de beforeEach()
.
La función setup()
devuelve un objeto literal
con las variables, como masterService
, a las que una prueba podría hacer referencia.
No defines variables semi-globales (por ejemplo, let masterService: MasterService
)
en el cuerpo de describe()
.
Luego, cada prueba invoca setup()
en su primera línea, antes de continuar
con pasos que manipulan al sujeto de prueba y afirman expectativas.
Observe cómo la prueba usa desestructuración de asignación para extraer las variables de configuración que necesita.
Muchos desarrolladores sienten que este enfoque es más limpio y explícito que el
que el estilo tradicional beforeEach()
.
Aunque esta guía de prueba sigue el estilo tradicional y
los esquemas CLI predeterminados
generan archivos de prueba con beforeEach()
y TestBed
,
no dudes en adoptar este enfoque alternativo en tus propios proyectos.
Pruebas de servicios HTTP
Los servicios de datos que realizan llamadas HTTP a servidores remotos normalmente inyectan y delegan
al servicio Angular HttpClient
para llamadas XHR.
Puedes probar un servicio de datos con un espía HttpClient
inyectado como lo harías
con cualquier servicio con una dependencia.
Los métodos del HeroService
devuelven Observables
. Debes
subscribirte a un observable para (a) hacer que se ejecute y (b)
afirmar que el método funciona o no.
El método subscribe()
toma una callback de éxito (next
) y una de falla (error
).
Asegurate de proporcionar ambas callback para capturar errores.
Si no lo haces, se produce un error observable asincrónico no detectado que el
test runner probablemente atribuirá a una prueba completamente diferente.
HttpClientTestingModule
Las interacciones extendidas entre un servicio de datos y el HttpClient
pueden ser complejas
y difícil de crear un mock con los espías.
El HttpClientTestingModule
puede hacer que estos escenarios de prueba sean más manejables.
Si bien el ejemplo de código que acompaña a esta guía muestra HttpClientTestingModule
,
esta página se remite a la guía Http,
que cubre las pruebas con el HttpClientTestingModule
en detalle.