Come eseguo il debug di un errore "[Object ErrorEvent] generato" nei miei test Karma / Jasmine?


108

Ho diversi test non riusciti che generano solo [object ErrorEvent] thrown. Non vedo nulla nella console che mi aiuti a individuare il codice offensivo. C'è qualcosa che devo fare per rintracciarli?

[EDIT]: Sto eseguendo Karma v1.70, Jasmine v2.7.0


Puoi includere più errori? Come più righe dell'errore prima e dopo?
Kevin

2
[object ErrorEvent] thrownè letteralmente tutto ciò che dice. Non c'è niente prima o dopo.
Darrell Brogdon

1
Per fortuna, ho appena ricevuto questo problema letteralmente nello stesso momento in cui stavi postando questa domanda, si è rivelato essere un tag di script "canaglia" (potrebbe anche essere un collegamento css) che doveva essere rimosso (il mio problema era correlato in CORS), o in caso di css, ho appena aggiunto crossorigin = "anonymous". Controlla il tuo codice per tali tag script / css, nel mio caso ho scoperto che il problema è causato da un componente completamente diverso!
TheDude

sei su cli angolare vero? @DarrellBrogdon
kuncevic.dev

1
@TheDude Come hai ristretto questo script? Linea per linea? O c'è stato un processo di debug che ti ha aiutato a restringere dove si trovava? Sto riscontrando lo stesso problema e l'unica informazione che devo continuare è il messaggio: è stato generato un errore in afterAll. Se isolo il test stesso passando it()a fit(), anche se è in esecuzione solo quel singolo test, l'errore viene comunque generato. Qualche consiglio di debug per questo tipo di errore?
Knight

Risposte:


121

FYI: puoi trovare l'errore esatto generato semplicemente aprendo DevTools Console una volta che i test sono in esecuzione.

Come soluzione rapida puoi provare a eseguire i tuoi test senza mappe di origine :

CLI v6.0.8 e versioni successive
--source-map=false

Prime versioni della CLI v6.0.x.
--sourceMap=false

CLI v1.x
--sourcemaps=false

Anche la scorciatoia ng test -sm=falsepotrebbe funzionare

C'è un problema aperto su questo https://github.com/angular/angular-cli/issues/7296

AGGIORNAMENTO : Ho avuto anche quel problema, quindi ho appena migrato all'ultima cli e mi sono assicurato che tutti i pacchetti siano aggiornati, package.jsoninoltre ho reinstallato completamente il node_modulesquindi ora il problema è scomparso.


3
questo ha funzionato per me. Ha contribuito a rivelare che il problema era con un'associazione di input non definita.
JP Lew

10
Per angular-cli 6, --sourceMap=falsesembra funzionare.
skermajo

1
tipica soluzione anteriore
Mcsky

1
Questa soluzione non funziona più. Una volta lo era, ma nella 6.2.4 non è così
Mike

3
Ottengo Uncaught [Object Object] lanciato in componenti casuali e in alcune esecuzioni non ottengo nulla ...: SI odio il test angolare.
Gerardo Buenrostro González

51

Se sourcemap = false non aiuta, prova a 1) aprire il browser eseguendo i test 2) fare clic sul pulsante di debug 3) aprire la console

L'errore sarà lì

inserisci qui la descrizione dell'immagine


8
Non avevo nemmeno bisogno di fare clic sul pulsante di debug. La sola apertura della console per sviluppatori ha funzionato per me.
chris31389

Brillante! Ho aggiunto l'opzione sourcemap ovunque, ma alla fine questo mi ha dato le informazioni di cui avevo bisogno
SkarXa,

1
La --sourcemaps=falsecosa non funzionava per me, ma ha funzionato perfettamente! Grazie!
mrClean

Non aiuta davvero se il browser si chiude subito dopo il test. Immagino che scriverò un mucchio di test inutili per tenere la finestra aperta, come una specie di cavernicolo.
CoryCoolguy

24

Prova se ricevi un messaggio di errore più descrittivo eseguendo il test dal terminale, in questo modo:

ng test -sm=false

Nel tuo test, puoi sostituire

it('should...')

con

fit('should...') 

Ora verranno eseguiti solo i test preceduti da fit . Per lasciare il browser aperto dopo aver eseguito il test, esegui il test in questo modo:

ng test -sm=false --single-run false

Personalmente, ho riscontrato questo errore due volte. Entrambi sono stati attivati ​​solo quando si chiama fixture.detectChanges ().

La prima volta l'ho risolto utilizzando l'interpolazione delle stringhe in modo più sicuro nel mio file .html.

Esempio non sicuro :

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

Esempio Safe (r) (nota il punto interrogativo):

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

Lo stesso può valere per l'associazione di proprietà:

<p [innerText]="user?.firstName"></p>

La seconda volta, stavo usando un DatePipe nel mio file .html, ma la proprietà mock su cui l'ho usato non era una data.

file .html:

<p>{{startDate | date: 'dd-MM-yyyy'}}</p>

File .ts (mock-data) ( sbagliato ):

let startDate = 'blablah';

File .ts (mock-data) ( corretto ):

let startDate = '2018-01-26';

Qualche commento perché "?" l'interpretazione delle stringhe è più sicura? Questo lavoro nel mio scenario.
Dylan Kapp

2
@DylanKapp controlla se l'oggetto è nullo prima di provare a leggere la proprietà dell'oggetto. Vedi angular.io/guide/template-syntax#safe-navigation-operator per maggiori dettagli.
Christian Rondeau

18

Questo perché il framework jasmine non può gestire il tipo ErrorEvent, quindi non estrae il messaggio di errore e chiama error.toString()invece quell'oggetto.

Ho appena presentato un problema a jasmine repo https://github.com/jasmine/jasmine/issues/1594

Finché non viene risolto, puoi applicare temporaneamente una patch al pacchetto jasmine installato nella cartella node_modules. Nel mio caso lo è

node_modules/jasmine/node_modules/lib/jasmine-core/jasmine.js

e quindi modificare l'implementazione di ExceptionFormatter da questo

if (error.name && error.message) {
    message += error.name + ': ' + error.message;
} else {
    message += error.toString() + ' thrown';
}

a questa

if (error.name && error.message) {
    message += error.name + ': ' + error.message;
} else if (error.message) {
    message += error.message;
} else {
    message += error.toString() + ' thrown';
}

Aiuta a identificare il problema.


3
Questo ha funzionato per me in jasmine-core@2.99.1. Tuttavia, ho dovuto collegarlo node_modules/jasmine_core/lib/jasmine_core/jasmine.js
Roger Garza

Così buono - ho impiegato un minuto per trovare questo post ma mi ha salvato il culo. Grazie. Stessa versione jasmine-core
Mr Rogers

Dopo averlo cambiato, è stato stampato solo uncaughtper me, il che non è stato d'aiuto. Quindi ho aggiunto il codice per stampare l' erroroggetto e le sue proprietà. if(error){ // message+=error; for(var propName in error) { propValue = error[propName] message+='error prop: '+propName+', value: '+propValue; } } . Questo ha fornito informazioni extra che mi hanno aiutato nel debugging - ad esempioerror prop: filename, value: blob:http://localhost:9881/11777e3a-28d8-414e-9047-cee7d328e843
Manu Chadha

7

Per me era correlato al fatto che una promessa fosse risolta in ngOnInitun componente. Ho dovuto usare async, fakeAsynce spuntare così come spegnendo il servizio asincrono conspyOn

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

Angular: come eseguire un test unitario con una chiamata di servizio asincrona


4

TL; DR: potrebbe essere correlato al test del routing.

Anch'io sto diventando [object ErrorEvent] thrown. Un'ora dopo, l'ho tracciato su una riga di codice.

this.username = this.userService.getUser(this.route.snapshot.paramMap.get('id'))[0];

Il problema sta con l'ambiente di test che tenta di valutare this.route.snapshot.paramMap.get('id') .

Se lo sostituisco con 0, se ne [object ErrorEvent] thrownva.

Il mio userService ha un utente così:

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

Quindi 0ottiene solo questo utente, in index 0.

In caso contrario, quando si esegue normalmente la mia app, this.route.snapshot.paramMap.get('id')viene valutato quando l'utente seleziona un utente da modificare dalla mia tabella degli utenti.

Quindi, nel mio HTML, *ngFor="let user of users; index as i"scorre per visualizzare tutti gli utenti, quindi routerLink="/edit/{{i}}"puoi fare clic sui pulsanti di modifica per ciascun utente, che se cliccato vai ad es. http://localhost:4200/edit/0Per modificare i dettagli dell'utente amministratore di cui sopra.


3

che dire della pulizia dopo ogni test case:

  afterEach(() => {
    TestBed.resetTestingModule();
  })

Ho letto da qualche parte che il TestBed viene ripristinato comunque per ogni test.
maggiore

1
Il mio caso ha aiutato a ripulire per i prossimi test.
Sebastian Brestin

1

Ho avuto lo stesso problema. Un modo in cui si verifica questo errore è quando si tenta di accedere a qualcosa di nullo o non definito nel modello. Assicurati di avere il controllo di sicurezza su quelle variabili.

Ad esempio, questo genererà [oggetto: ErrorEvent] quando la configurazione non è definita al caricamento del componente.

template.html

<div *ngIf="config.options">
   .....
   ......
</div>

Fallo invece

<div *ngIf="config?.options">
   .....
   ......
</div>

1

Ciò che può aiutarti è, se hai la finestra di Chrome aperta per il tuo test runner Karma, aprire gli strumenti per sviluppatori e controllare la console lì. Per me, questo mi ha aiutato a scoprire che l'app non poteva utilizzare il metodo Array.findIndex su un array non definito (perché la struttura dei dati era organizzata da una stringa di data, come data [2018] [3] [28] e Mi è capitato di indicare la data sbagliata), ma invece di fermarsi all'errore, il test ha continuato a funzionare.


Grazie mille! Mi sarei aspettato che le informazioni fossero presenti nella console, hai salvato un paio d'ore della mia vita :)
Sébastien Tromp

0

Per me il problema era che avevo un test in cui stavo accidentalmente utilizzando la libreria auth0-lock .


0

Sembrava essere un problema asincrono, perché dopo aver aggiunto un numero sufficiente di messaggi itin una delle specifiche del mio componente, sono stato in grado di ottenere un messaggio di errore utilizzabile che indicava un file e una riga all'interno di quel file (era correlato aparamMap .

Nelle specifiche che hanno testato ParamMap, ho appena aggiunto:

  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();
    });
  });

0

Potresti avere una gara o un test asincrono che non è impostato correttamente o è utilizzato in modo errato. Presumo che il caso di debug debba essere corretto e ignoro che la riga di comando passa. Continua ad aggiornare il karma test runner (browser) nel caso in cui l'errore[object ErrorEvent] thrown venga visualizzato in modo intermittente, quindi assicurati di aver implementato correttamente la condizione asincrona.

Si spera che funzioni.


0

[Object ErrorEvent] lanciato

Questo errore mostra che hai qualcosa di indefinito. Il modo più semplice per eseguire il debug dalla mia esperienza è:

it('should create', () => {
    console.log(component);
    // You can check in the browser log which property is undefined
    });

Questo in realtà si è rivelato il promemoria più utile di tutti: nei miei test ho un finto servizio di autenticazione, che mancava un metodo. Apparentemente non correlato, uno dei test in un componente non è riuscito, ma non quando è stato isolato. Ho rintracciato l'oscuro [object ErrorEvent] thrownfino a quel metodo mancante remoto solo grazie a
console.log

0

Nel mio caso il problema era con il servizio, poiché uno degli oggetti non sarà definito durante l'esecuzione dei test.

Il codice di esempio del servizio era qualcosa di simile al di sotto dell'accesso a dom,

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

Le specifiche che fanno riferimento a questo servizio hanno avuto esito negativo con l'errore " [Object ErrorEvent] generato ".

Ho deriso il mio oggetto di servizio all'interno di tutte le specifiche che si riferivano a questo e il problema è stato risolto.

Servizio finto

class MockService {
serviceMethod(div) : void {
  testElement = document.querySelector('div') as HTMLElement;
  return testElement;
  } 
}

E usa questo finto oggetto di servizio nei provider come di seguito,

beforeEach(async(() => {

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

0

Stavo usando un proxy nella mia applicazione definito in proxy.conf.json come:

'/api': { 'target': 'some path', 'changeOrigin': false }

Poiché Karma non era a conoscenza di questo proxy, continuava a riscontrare errori nella console che impedivano di trovare l'endpoint API. Quindi, dopo aver guardato nella documentazione di Karma, ho scoperto che quello che potevo fare era aggiungere la proprietà "proxies" in karma.conf.js con lo stesso oggetto da proxy.conf.json:

proxies: { '/api': { 'target': 'some path', 'changeOrigin': false }}

L'errore nella console era scomparso e l '[object errorEvent] non veniva più lanciato.


Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.