¿Cómo depuro un error "[object ErrorEvent] arrojado" en mis pruebas de Karma / Jasmine?

108

Tengo varias pruebas fallidas que solo dan salida [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

Darrell Brogdon
fuente
¿Puede incluir más errores? ¿Te gustan varias líneas del error antes y después?
Kevin
2
[object ErrorEvent] thrownes literalmente todo lo que dice. No hay nada antes ni después.
Darrell Brogdon
1
Por suerte, recibí este problema literalmente al mismo tiempo que publicabas esta pregunta, resultó ser una etiqueta de script "deshonesta" (también podría ser un enlace css) que debía eliminarse (mi problema estaba relacionado a CORS), o en el caso de CSS, acabo de agregar crossorigin = "anonymous". Verifique su código para tales etiquetas de script / css, en mi caso encontré que el problema fue causado por un componente totalmente diferente.
TheDude
estás en angular cli, ¿no? @DarrellBrogdon
kuncevic.dev
1
@TheDude ¿Cómo redujo este guión? ¿Linea por linea? ¿O hubo algún proceso de depuración que le ayudó a determinar dónde estaba? Tengo el mismo problema y la única información que tengo para continuar es el mensaje: Se lanzó un error afterAll. Si aíslo la prueba en sí cambiando it()a fit(), aunque solo se esté ejecutando esa única prueba, el error aún se produce. ¿Alguna recomendación de depuración para este tipo de error?
Knight

Respuestas:

121

Para su información: puede encontrar el error exacto arrojado con solo abrir la Consola DevTools una vez que se están ejecutando sus pruebas.

Como solución rápida, puede intentar ejecutar sus pruebas sin mapas de origen :

CLI v6.0.8 y superior
--source-map=false

Versiones anteriores de CLI v6.0.x
--sourceMap=false

CLI v1.x
--sourcemaps=false

El acceso directo ng test -sm=falsetambién podría funcionar

Hay un problema abierto al respecto https://github.com/angular/angular-cli/issues/7296

ACTUALIZACIÓN : También tuve ese problema, así que simplemente migré a la última cli y me aseguré de que todos los paquetes estén actualizados y package.jsonreinstalé por completo el, node_modulesasí que ahora el problema ha desaparecido.

kuncevic.dev
fuente
3
esto funcionó para mí. Ayudó a revelar que el problema estaba en un enlace de entrada indefinido.
JP Lew
10
Para angular-cli 6, --sourceMap=falseparece funcionar.
skermajo
1
solución frontal típica
Mcsky
1
Esta solución ya no funciona. Solía ​​hacerlo, pero en 6.2.4 no lo hace
Mike
3
Obtengo [Object Object] sin capturar en componentes aleatorios y en algunas ejecuciones no obtengo nada ...: SI odio las pruebas angulares.
Gerardo Buenrostro González
51

Si sourcemap = false no ayuda, intente 1) abrir su navegador ejecutando las pruebas 2) hacer clic en el botón de depuración 3) abrir la consola

El error estará ahí

ingrese la descripción de la imagen aquí

Victor Bredihin
fuente
8
Ni siquiera necesité hacer clic en el botón de depuración. Simplemente abrir la consola de desarrollo funcionó para mí.
chris31389
¡Brillante! Agregué la opción de mapa de fuentes en todas partes, pero al final esto me dio la información que necesitaba
SkarXa
1
La --sourcemaps=falsecosa no estaba funcionando para mí, ¡pero funcionó perfectamente! ¡Gracias!
mrClean
Realmente no ayuda si el navegador se cierra inmediatamente después de la prueba. Supongo que escribiré un montón de pruebas inútiles para mantener la ventana abierta, como una especie de cavernícola.
CoryCoolguy
24

Intente si obtiene un mensaje de error más descriptivo ejecutando la prueba desde el terminal, como este:

ng test -sm=false

En su prueba, puede reemplazar

it('should...')

con

fit('should...') 

Ahora solo se ejecutarán las pruebas precedidas por 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) (observe el signo de interrogación):

<p>{{user?.firstName}}</p>

Lo mismo puede aplicarse a la propiedad vinculante:

<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';
harryvederci
fuente
Algún comentario por qué '?' ¿La interpretación de cadenas es más segura? Este trabajo en mi escenario.
Dylan Kapp
2
@DylanKapp esto comprueba si el objeto es nulo antes de intentar leer la propiedad del objeto. Consulte angular.io/guide/template-syntax#safe-navigation-operator para obtener más detalles.
Christian Rondeau
18

Esto se debe a que el marco jasmine no puede manejar el tipo ErrorEvent, por lo que no extrae el mensaje de error y llama error.toString()a ese objeto.

Acabo de presentar un problema en el repositorio de jasmine https://github.com/jasmine/jasmine/issues/1594

Siempre que no esté arreglado, puede parchear temporalmente su paquete jasmine 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 de esto

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.

Ginie
fuente
3
Esto funcionó para mí en [email protected]. Sin embargo, tuve que parchearlo node_modules/jasmine_core/lib/jasmine_core/jasmine.js
Roger Garza
Muy bien, me tomó un minuto encontrar esta publicación, pero me salvó el trasero. Gracias. Misma versión con núcleo de jazmín
mr rogers
Después de cambiar esto, solo se imprimió uncaughtpara mí, lo que no fue útil. Entonces agregué código para imprimir el errorobjeto y sus propiedades. if(error){ // message+=error; for(var propName in error) { propValue = error[propName] message+='error prop: '+propName+', value: '+propValue; } } . Esto proporcionó información adicional que me ayudó a depurar, por ejemploerror prop: filename, value: blob:http://localhost:9881/11777e3a-28d8-414e-9047-cee7d328e843
Manu Chadha
7

Para mí, estaba relacionado con tener una promesa resuelta en el ngOnInitde un componente. Tuve que usar async, fakeAsyncmarcar y eliminar el servicio asincrónico conspyOn

beforeEach(async(
  //... initialise testbed and component
))
beforeEach(fakeAsync(
  // ... setup mocks then call:
  component.ngOnInit()
  tick()
  fixture.detectChanges()
))

Angular: cómo probar un componente con una llamada de servicio asincrónica

roo2
fuente
4

TL; DR: Puede estar relacionado con la prueba de enrutamiento.

Yo [object ErrorEvent] throwntambién. Una hora más tarde, 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 el entorno de prueba que intenta evaluar this.route.snapshot.paramMap.get('id').

Si lo reemplazo con 0, [object ErrorEvent] throwndesaparece.

Mi userService tiene un usuario así:

public users = [ ["admin", "First name", "Surname", etc... ] ].

Así que 0solo obtiene este usuario, en index 0.

De lo contrario, cuando normalmente se ejecuta 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, se *ngFor="let user of users; index as i"repite para mostrar todos los usuarios y luego routerLink="/edit/{{i}}"puede hacer clic en los botones de edición para cada usuario, que cuando se hace clic en, van a, por ejemplo, http://localhost:4200/edit/0para editar los detalles del usuario administrador antes mencionado.

León
fuente
3

¿Qué pasa con la limpieza después de cada caso de prueba?

  afterEach(() => {
    TestBed.resetTestingModule();
  })
Sebastián Brestin
fuente
Leí en alguna parte que TestBed se reinicia de todos modos para cada prueba.
bgerth
1
En mi caso, ayudó a limpiar para las próximas pruebas.
Sebastian Brestin
1

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 control de seguridad en esas variables.

Por ejemplo, esto arrojará [object: ErrorEvent] 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>
kashpatel
fuente
1

Lo que puede ayudar es que, si tiene la ventana de Chrome abierta para su ejecutor de prueba de Karma, abra las herramientas de desarrollador y verifique 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 data [2018] [3] [28], y Sucedió que estaba apuntando a la fecha incorrecta), pero sin embargo, en lugar de simplemente detenerme en el error, la prueba siguió ejecutándose.

OzzyTheGiant
fuente
¡Gracias un montón! Hubiera esperado que la información estuviera presente en la consola, me salvaste un par de horas de mi vida :)
Sébastien Tromp
0

Para mí, el problema fue que tuve una prueba en la que accidentalmente estaba usando la biblioteca auth0-lock .

Manolis
fuente
0

Parecía ser un problema asincrónico, porque después de agregar suficientes its 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();
    });
  });
inorgánico
fuente
0

Es posible que tenga una prueba de carrera o asíncrona que no esté bien configurada o que se use incorrectamente. Asumiría que el caso de depuración debe arreglarse e ignorar que pasa la línea de comando. Simplemente siga actualizando el ejecutor de pruebas de karma (navegador) en caso de que el error [object ErrorEvent] thrownaparezca de forma intermitente, luego asegúrese de haber implementado la condición asíncrona correctamente.

Ojalá esto funcione.

Pradosh kumar Mohapatra
fuente
0

[object ErrorEvent] lanzado

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
    });
Daniel Dimitrov
fuente
En realidad, este ha resultado ser el recordatorio más útil de todos: en mis pruebas tengo un servicio de autenticación simulado, al que se le pasó un método. Aparentemente sin relación alguna, una de las pruebas de un componente falló, pero no cuando se aisló. He rastreado lo oscuro [object ErrorEvent] thrownhasta ese método remoto perdido solo gracias a console.log :)
RedDree
0

En mi caso, el problema fue con el servicio, ya que uno de los objetos no estará definido durante la ejecución de las pruebas.

La muestra de código de servicio era algo así como el acceso a dom,

  const elem = this.document.querySelector(element) as HTMLElement;
  elem.scrollIntoView({param1: ''});

Las especificaciones que hacen referencia a este servicio fallaban con el error ' [object 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 los proveedores como se muestra a continuación,

beforeEach(async(() => {

TestBed.configureTestingModule({
  declarations: [Component],
  providers: [
     { provide: Service, useClass: MockService },
    ],
})
  .compileComponents();
}));
Vishwa G
fuente
0

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, siguió arrojando errores en la consola de que no se podía 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 [object errorEvent] ya no se lanzó.

Arnold Layne
fuente
-1

Al final, lo que me funcionó:

    TestBed.resetTestingModule();
  })
Igor Korchagin
fuente