tutorial - unit test angular 6
¿Cómo depuro un error "[objeto ErrorEvent] arrojado" en mis pruebas de Karma/Jasmine? (16)
[objeto ErrorEvent] arrojado
Este error muestra que tienes algo indefinido. La forma más fácil de depurarlo desde mi experiencia es:
it(''should create'', () => {
console.log(component);
// You can check in the browser log which property is undefined
});
Tengo varias pruebas
[object ErrorEvent] thrown
que solo
[object ErrorEvent] thrown
.
No veo nada en la consola que me ayude a identificar el código ofensivo.
¿Hay algo que deba hacer para localizarlos?
[EDITAR]: estoy ejecutando Karma v1.70, Jasmine v2.7.0
¿Qué pasa con la limpieza después de cada caso de prueba?
afterEach(() => {
TestBed.resetTestingModule();
})
Al final, lo que puede funcionar para mí:
TestBed.resetTestingModule();
})
En mi caso, el problema era con el servicio, ya que uno de los objetos no estará definido durante la ejecución de las pruebas.
El ejemplo de código de servicio era algo así como debajo del acceso a dom,
const elem = this.document.querySelector(element) as HTMLElement;
elem.scrollIntoView({param1: ''''});
Las especificaciones que se refieren a este servicio estaban fallando con el error '' [objeto ErrorEvent] arrojado ''.
Me burlé de mi objeto de servicio dentro de todas las especificaciones que se referían a esto y el problema se resolvió.
Servicio simulado
class MockService {
serviceMethod(div) : void {
testElement = document.querySelector(''div'') as HTMLElement;
return testElement;
}
}
Y use este objeto de servicio simulado en proveedores como se muestra a continuación,
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [Component],
providers: [
{ provide: Service, useClass: MockService },
],
})
.compileComponents();
}));
Es posible que tenga una prueba de carrera o asíncrona que no está configurada del todo bien o se usa incorrectamente.
Asumiría que el caso de depuración debe repararse e ignoraría que pasa la línea de comando.
Simplemente siga actualizando el corredor de prueba de karma (navegador) en caso de
[object ErrorEvent] thrown
el error
[object ErrorEvent] thrown
intermitente, luego asegúrese de haber implementado la condición asíncrona correctamente.
Ojalá esto funcione.
Estaba usando un proxy en mi aplicación definida en proxy.conf.json como:
''/api'': { ''target'': ''some path'', ''changeOrigin'': false }
Debido a que Karma no estaba al tanto de este proxy, seguía generando errores en la consola de que no se pudo encontrar el punto final de la API. Entonces, después de buscar en la documentación de Karma, descubrí que lo que podía hacer era agregar la propiedad "proxies" en karma.conf.js con el mismo objeto del proxy.conf.json:
proxies: { ''/api'': { ''target'': ''some path'', ''changeOrigin'': false }}
El error en la consola desapareció y el [objeto errorEvent] ya no se lanzó.
Esto se debe a que el marco de jazmín no puede manejar el tipo ErrorEvent, por lo que no extrae el mensaje de error y llama a
error.toString()
en ese objeto.
Acabo de presentar un problema en el repositorio de jazmín https://github.com/jasmine/jasmine/issues/1594
Mientras no se arregle, puede parchear temporalmente su paquete de jazmín instalado en la carpeta node_modules. En mi caso es
node_modules/jasmine/node_modules/lib/jasmine-core/jasmine.js
y luego cambie la implementación de ExceptionFormatter a partir de este
if (error.name && error.message) {
message += error.name + '': '' + error.message;
} else {
message += error.toString() + '' thrown'';
}
a esto
if (error.name && error.message) {
message += error.name + '': '' + error.message;
} else if (error.message) {
message += error.message;
} else {
message += error.toString() + '' thrown'';
}
Ayuda a identificar el problema.
Lo que puede ayudar es, si tiene la ventana de Chrome abierta para su corredor de prueba Karma, abrir las herramientas de desarrollador y verificar la consola allí. Para mí, esto me ayudó a descubrir que la aplicación no podía usar el método Array.findIndex en una matriz indefinida (porque la estructura de datos estaba organizada por una cadena de fecha, como datos [2018] [3] [28], y Estaba señalando la fecha incorrecta), pero en lugar de detenerme ante el error, la prueba siguió ejecutándose.
Para mí, el problema era que tenía una prueba en la que accidentalmente estaba usando la biblioteca auth0-lock .
Para mí, estaba relacionado con tener una promesa resuelta en el
ngOnInit
de un componente.
Tuve que usar
async
,
fakeAsync
y tick, así como eliminar el servicio async con
spyOn
beforeEach(async(
//... initialise testbed and component
))
beforeEach(fakeAsync(
// ... setup mocks then call:
component.ngOnInit()
tick()
fixture.detectChanges()
))
Angular: cómo unificar el componente de prueba con una llamada de servicio asincrónica
Para solucionarlo, debe ejecutar sus pruebas sin mapas de origen como solución alternativa:
CLI v6.0.8 y superior
--source-map=false
CLI v6.0.x versiones anteriores
--sourceMap=false
CLI v1.x
--sourcemaps=false
ng test -sm=false
directong test -sm=false
también podría funcionar
Hay un problema abierto en ese https://github.com/angular/angular-cli/issues/7296
ACTUALIZACIÓN
: También tuve ese problema, así que simplemente migré al último cli y me aseguré de que todos los paquetes estén actualizados en
package.json
también reinstalé completamente los
node_modules
así que ahora el problema desapareció.
Parecía ser un problema asíncrono, porque después de agregar lo suficiente en una de las especificaciones de mis componentes, pude obtener un mensaje de error utilizable que apuntaba a un archivo y una línea dentro de ese archivo (estaba relacionado con
paramMap
.
En la especificación que probó ParamMap, acabo de agregar:
describe(''this test'', () => {
it(''will succeed'', () => {
expect(true).toBeTruthy();
});
it(''will succeed'', () => {
expect(true).toBeTruthy();
});
it(''will succeed'', () => {
expect(true).toBeTruthy();
});
it(''will succeed'', () => {
expect(true).toBeTruthy();
});
});
Pruebe si recibe un mensaje de error más descriptivo ejecutando la prueba desde el terminal, de esta manera:
ng test -sm=false
En su prueba, puede reemplazar
it(''should...'')
con
fit(''should...'')
Ahora solo se ejecutarán las pruebas precedidas por el ajuste . Para dejar el navegador abierto después de ejecutar la prueba, ejecute la prueba de esta manera:
ng test -sm=false --single-run false
Personalmente, he encontrado este error dos veces. Ambos solo se activaron al llamar a fixture.detectChanges ().
La primera vez, lo resolví usando la interpolación de cadenas de manera más segura en mi archivo .html.
Ejemplo inseguro :
<p>{{user.firstName}}</p>
Ejemplo de Safe (r) (tenga en cuenta el signo de interrogación):
<p>{{user?.firstName}}</p>
Lo mismo puede aplicarse al enlace de propiedad:
<p [innerText]="user?.firstName"></p>
La segunda vez, estaba usando un DatePipe en mi archivo .html, pero la propiedad simulada en la que lo usé no era una fecha.
archivo .html:
<p>{{startDate | date: ''dd-MM-yyyy''}}</p>
Archivo .ts (datos simulados) ( incorrecto ):
let startDate = ''blablah'';
Archivo .ts (datos simulados) ( correcto ):
let startDate = ''2018-01-26'';
Yo tuve el mismo problema. Una forma en que ocurre este error es cuando intenta acceder a algo nulo o indefinido en la plantilla. Asegúrese de tener un control de seguridad en esas variables.
Por ejemplo, esto arrojará [objeto: Evento de error] cuando la configuración no está definida en la carga del componente.
template.html
<div *ngIf="config.options">
.....
......
</div>
Haz esto en su lugar
<div *ngIf="config?.options">
.....
......
</div>
TL; DR: puede estar relacionado con el enrutamiento de prueba.
Estoy recibiendo
[object ErrorEvent] thrown
también.
Una hora después, lo rastreó hasta una línea de código.
this.username = this.userService.getUser(this.route.snapshot.paramMap.get(''id''))[0];
El problema radica en que el entorno de prueba intenta evaluar
this.route.snapshot.paramMap.get(''id'')
.
Si lo reemplazo con
0
,
[object ErrorEvent] thrown
desaparece.
Mi userService tiene un usuario así:
public users = [ ["admin", "First name", "Surname", etc... ] ].
Entonces
0
solo obtiene este usuario, en el índice
0
.
De lo contrario, cuando normalmente
this.route.snapshot.paramMap.get(''id'')
mi aplicación,
this.route.snapshot.paramMap.get(''id'')
se evalúa cuando el usuario selecciona un usuario para editar de mi tabla de usuarios.
Entonces, en mi HTML,
*ngFor="let user of users; index as i"
bucles para mostrar todos los usuarios y luego
routerLink="/edit/{{i}}"
para que pueda hacer clic en los botones de edición para cada usuario, que cuando haga clic en ir a, por ejemplo,
http://localhost:4200/edit/0
para editar los detalles del usuario administrador antes mencionados.