Comment déboguer une erreur «[object ErrorEvent] thrown» dans mes tests Karma / Jasmine?

108

J'ai plusieurs tests échouants qui ne produisent que [object ErrorEvent] thrown. Je ne vois rien dans la console qui m'aide à identifier le code incriminé. Dois-je faire quelque chose pour les retrouver?

[EDIT]: J'utilise Karma v1.70, Jasmine v2.7.0

Darrell Brogdon
la source
Pouvez-vous inclure plus de l'erreur? Comme plusieurs lignes de l'erreur avant et après?
Kevin
2
[object ErrorEvent] thrownest littéralement tout ce qu'il dit. Il n'y a rien avant ou après.
Darrell Brogdon
1
Par chance, je viens de recevoir ce problème littéralement au moment où vous posiez cette question, il s’est avéré être une balise de script «non autorisée» (cela pouvait aussi être un lien css) qui devait être supprimée (mon problème était lié à CORS), ou en cas de css, je viens d'ajouter crossorigin = "anonymous". Vérifiez votre code pour de telles balises script / css, dans mon cas, j'ai trouvé que le problème était causé par un composant totalement différent!
TheDude
êtes-vous sur cli angulaire n'est-ce pas? @DarrellBrogdon
kuncevic.dev
1
@TheDude Comment avez-vous affiné ce script? Ligne par ligne? Ou y avait-il un processus de débogage qui vous a aidé à préciser où il se trouvait? J'ai le même problème et la seule information sur laquelle je dois continuer est le message: Une erreur a été générée dans afterAll. Si j'isole le test lui-même en passant it()à fit(), même si seul ce test unique est en cours d'exécution, l'erreur est toujours renvoyée. Des recommandations de débogage pour ce type d'erreur?
Knight

Réponses:

121

FYI: vous pouvez trouver l'erreur exacte générée simplement en ouvrant la console DevTools une fois que vos tests sont en cours d'exécution.

En guise de correctif rapide, vous pouvez essayer d'exécuter vos tests sans sourcemaps :

CLI v6.0.8 et supérieur
--source-map=false

CLI v6.0.x premières versions
--sourceMap=false

CLI v1.x
--sourcemaps=false

Le raccourci ng test -sm=falsepeut également fonctionner

Il y a un problème ouvert à ce sujet https://github.com/angular/angular-cli/issues/7296

MISE À JOUR : J'ai eu ce problème aussi, donc j'ai juste migré vers le dernier cli et m'assure que tous les paquets sont mis à jour package.jsonaussi j'ai complètement réinstallé le node_modulesdonc maintenant le problème a disparu.

kuncevic.dev
la source
3
cela a fonctionné pour moi. Cela a permis de révéler que le problème était lié à une liaison d'entrée non définie.
JP Lew
10
Pour angular-cli 6, --sourceMap=falsesemble fonctionner.
skermajo
1
solution frontale typique
Mcsky
1
Cette solution ne fonctionne plus. C'était le cas, mais en 6.2.4, ce n'est pas le cas
Mike
3
Je reçois Uncaught [objet objet] jeté dans des composants aléatoires et dans certaines courses je n'obtiens rien ...: SI déteste les tests angulaires.
Gerardo Buenrostro González
51

Si sourcemap = false ne vous aide pas, essayez 1) d'ouvrir votre navigateur en exécutant les tests 2) cliquez sur le bouton de débogage 3) ouvrez la console

L'erreur sera là

entrez la description de l'image ici

Victor Bredihin
la source
8
Je n'ai même pas besoin de cliquer sur le bouton de débogage. Le simple fait d'ouvrir la console développeur a fonctionné pour moi.
chris31389
Brillant! J'ai ajouté l'option de sourcemap partout, mais à la fin, cela m'a donné les informations dont j'avais besoin
SkarXa
1
La --sourcemaps=falsechose ne fonctionnait pas pour moi, mais cela fonctionnait parfaitement! Je vous remercie!
mrClean
Cela n'aide pas vraiment si le navigateur se ferme juste après le test. Je suppose que je vais écrire un tas de tests inutiles pour garder la fenêtre ouverte, comme une sorte d'homme des cavernes.
CoryCoolguy
24

Essayez si vous obtenez un message d'erreur plus descriptif en exécutant le test à partir du terminal, comme ceci:

ng test -sm=false

Dans votre test, vous pouvez remplacer

it('should...')

avec

fit('should...') 

Désormais, seuls les tests précédés de fit seront exécutés. Pour laisser le navigateur ouvert après avoir exécuté le test, exécutez le test comme ceci:

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

Personnellement, j'ai rencontré cette erreur deux fois. Les deux n'étaient déclenchés que lors de l'appel de fixture.detectChanges ().

La première fois, je l'ai résolu en utilisant l'interpolation de chaîne de manière plus sûre dans mon fichier .html.

Exemple dangereux :

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

Exemple Safe (r) (notez le point d'interrogation):

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

La même chose peut s'appliquer à la liaison de propriété:

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

Le second fois, j'utilisais un DatePipe dans mon fichier .html, mais la propriété fictive sur laquelle je l'ai utilisée n'était pas une date.

Fichier .html:

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

Fichier .ts (mock-data) ( faux ):

let startDate = 'blablah';

Fichier .ts (mock-data) ( correct ):

let startDate = '2018-01-26';
harryvederci
la source
Un commentaire pourquoi '?' l'interprétation des cordes est-elle plus sûre? Ce travail dans mon scénario.
Dylan Kapp
2
@DylanKapp ceci vérifie si l'objet est nul avant d'essayer de lire la propriété de l'objet. Voir angular.io/guide/template-syntax#safe-navigation-operator pour plus de détails.
Christian Rondeau
18

Cela est dû au fait que le framework jasmine ne peut pas gérer le type ErrorEvent afin qu'il n'extrait pas le message d'erreur et appelle error.toString() à la place cet objet.

Je viens de déposer un problème chez jasmine repo https://github.com/jasmine/jasmine/issues/1594

Tant qu'il n'est pas corrigé, vous pouvez temporairement patcher votre package jasmine installé dans le dossier node_modules. Dans mon cas c'est

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

puis modifiez l'implémentation de ExceptionFormatter à partir de ce

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

pour ça

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

Cela aide à identifier le problème.

Ginie
la source
3
Cela a fonctionné pour moi dans [email protected]. Cependant, j'ai dû le patcher node_modules/jasmine_core/lib/jasmine_core/jasmine.js
Roger Garza
Tellement bon - a pris une minute pour trouver ce message, mais cela m'a sauvé les fesses. Merci. Même version de noyau de jasmin
Mr Rogers
Après avoir changé cela, il ne s'est imprimé que uncaughtpour moi, ce qui n'a pas été utile. J'ai donc ajouté du code pour imprimer l' errorobjet et ses propriétés. if(error){ // message+=error; for(var propName in error) { propValue = error[propName] message+='error prop: '+propName+', value: '+propValue; } } . Cela a fourni des informations supplémentaires qui m'ont aidé à déboguer - par exempleerror prop: filename, value: blob:http://localhost:9881/11777e3a-28d8-414e-9047-cee7d328e843
Manu Chadha
7

Pour moi, c'était lié au fait d'avoir une promesse résolue dans ngOnInitun composant. J'ai dû utiliser async, fakeAsynccocher et supprimer le service asynchrone avecspyOn

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

Angular - Comment tester un composant avec un appel de service asynchrone

roo2
la source
4

TL; DR: Cela peut être lié au test du routage.

Je reçois [object ErrorEvent] thrownaussi. Une heure plus tard, il a retracé une ligne de code.

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

Le problème réside dans l'environnement de test qui tente d'évaluer this.route.snapshot.paramMap.get('id') .

Si je le remplace par 0,[object ErrorEvent] thrown disparaît.

Mon userService a un utilisateur comme ceci:

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

Alors 0obtient juste cet utilisateur, à l'index0 .

Sinon, lorsque j'exécute normalement mon application, this.route.snapshot.paramMap.get('id') est évalué lorsque l'utilisateur sélectionne un utilisateur à modifier dans ma table d'utilisateurs.

Donc, dans mon HTML, *ngFor="let user of users; index as i"boucle pour afficher tous les utilisateurs routerLink="/edit/{{i}}"afin que vous puissiez cliquer sur les boutons d'édition pour chaque utilisateur, qui, lorsqu'ils sont cliqués, vont par exemple http://localhost:4200/edit/0pour modifier les détails de l'utilisateur administrateur susmentionné.

Leo
la source
3

qu'en est-il du nettoyage après chaque cas de test:

  afterEach(() => {
    TestBed.resetTestingModule();
  })
Sébastien Brestin
la source
J'ai lu quelque part que le TestBed est réinitialisé de toute façon pour chaque test.
bgerth
1
Dans mon cas, cela a aidé à nettoyer pour les prochains tests.
Sebastian Brestin
1

J'ai eu le même problème. Cette erreur se produit notamment lorsque vous essayez d'accéder à tout élément nul ou non défini dans le modèle. Assurez-vous d'avoir un contrôle de sécurité sur ces variables.

Par exemple, cela lancera [object: ErrorEvent] lorsque la configuration n'est pas définie lors du chargement du composant.

template.html

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

Faites ceci à la place

<div *ngIf="config?.options">
   .....
   ......
</div>
Kashpatel
la source
1

Ce qui peut aider, si vous avez la fenêtre Chrome ouverte pour votre lanceur de test Karma, ouvrez les outils de développement et vérifiez la console. Pour moi, cela m'a aidé à découvrir que l'application ne pouvait pas utiliser la méthode Array.findIndex sur un tableau non défini (car la structure de données était organisée par une chaîne de date, telle que data [2018] [3] [28], et Il se trouve que j'ai indiqué la mauvaise date), mais au lieu de simplement m'arrêter à l'erreur, le test a continué à fonctionner.

OzzyTheGiant
la source
Merci beaucoup! Je m'attendais à ce que l'info soit présente dans la console, vous avez sauvé quelques heures de ma vie :)
Sébastien Tromp
0

Pour moi, le problème était que j'avais un test où j'utilisais accidentellement la bibliothèque auth0-lock .

Manolis
la source
0

Cela semblait être un problème asynchrone, car après avoir ajouté suffisamment de its dans l'une de mes spécifications de composant, j'ai pu obtenir un message d'erreur utilisable qui pointait vers un fichier et une ligne dans ce fichier (il était lié à paramMap.

Dans la spécification qui a testé ParamMap, je viens d'ajouter:

  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();
    });
  });
inorganik
la source
0

Vous pouvez avoir une course ou un test asynchrone qui n'est pas tout à fait correctement configuré ou qui n'est pas utilisé correctement. Je suppose que le cas de débogage doit être corrigé et ignorer que la ligne de commande passe. Continuez simplement à actualiser le testeur de karma (navigateur) en cas d'erreur[object ErrorEvent] thrown apparaîtrait par intermittence, puis assurez-vous d'avoir correctement implémenté la condition asynchrone.

Espérons que cela fonctionne.

Pradosh kumar Mohapatra
la source
0

[object ErrorEvent] jeté

Cette erreur indique que vous avez quelque chose d'indéfini. Le moyen le plus simple de le déboguer d'après mon expérience est:

it('should create', () => {
    console.log(component);
    // You can check in the browser log which property is undefined
    });
Daniel Dimitrov
la source
Cela s'est avéré être le rappel le plus utile de tous: dans mes tests, j'ai un faux service d'authentification, qui a manqué une méthode. Apparemment sans rapport, l'un des tests d'un composant a échoué, mais pas lorsqu'il est isolé. J'ai retracé l'obscur [object ErrorEvent] thrownjusqu'à cette méthode manquante à distance uniquement grâce à console.log :)
RedDree
0

Dans mon cas, le problème était avec le service, car l'un des objets ne sera pas défini lors des tests en cours.

L'exemple de code de service était quelque chose comme ci-dessous l'accès à dom,

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

Les spécifications faisant référence à ce service échouaient avec l'erreur « [object ErrorEvent] thrown ».

Je me suis moqué de mon objet de service dans toutes les spécifications qui faisaient référence à cela et le problème a été résolu.

Service simulé

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

Et utilisez cet objet de service simulé dans les fournisseurs comme ci-dessous,

beforeEach(async(() => {

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

J'utilisais un proxy dans mon application défini dans proxy.conf.json comme:

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

Comme Karma n'était pas au courant de ce proxy, il n'arrêtait pas de tracer des erreurs dans la console indiquant que le point de terminaison de l'API était introuvable. Donc, après avoir regardé dans la documentation de Karma, j'ai découvert que ce que je pouvais faire était d'ajouter la propriété "proxies" dans karma.conf.js avec le même objet du proxy.conf.json:

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

L'erreur dans la console a disparu et l '[object errorEvent] n'est plus renvoyé.

Arnold Layne
la source
-1

En fin de compte, ce qui a fonctionné pour moi:

    TestBed.resetTestingModule();
  })
Igor Korchagin
la source