web-dev-qa-db-fra.com

Tests unitaires angulaires 6: une erreur a été générée après after\nReferenceError: variable introuvable: $ levée

Lors de l'exécution de mes tests unitaires, de temps en temps, même s'ils réussissent, à la fin de tous les tests en cours, l'erreur suivante apparaîtra.

Sur ma version de Jenkins CI exécutant PhantomJS:

.PhantomJS 2.1.1 (Linux 0.0.0) ERROR
  {
    "message": "An error was thrown in afterAll\nReferenceError: Can't find variable: $ thrown",
    "str": "An error was thrown in afterAll\nReferenceError: Can't find variable: $ thrown"
  }

Ou sur Chrome:

Chrome 67.0.3396 (Windows 7 0.0.0) ERROR
  {
    "message": "An error was thrown in afterAll\n[object ErrorEvent] thrown",
    "str": "An error was thrown in afterAll\n[object ErrorEvent] thrown"
  }

J'ai aussi des tests vraiment peu fiables, sans rien changer, parfois ils réussiraient et d'autres fois, les mêmes tests échoueraient, alors je savais qu'il se passait quelque chose de bizarre. 

6
Oisin

Nous étions confrontés à des problèmes similaires, à la fois avec la même erreur intermittente et les tests d'échec intermittents. Cela semble être dû au fait que lors de la mise à niveau vers Angular 6, nous avions également mis à niveau vers Jasmine 3, dans lequel l'exécution de tests dans un ordre aléatoire est apparemment maintenant la méthode par défaut. En définissant random sur false, nous ne voyons plus ces problèmes. Nous l'avons fait en ajoutant ce paramètre dans le fichier karma.conf.js:

  config.set({
    client: {
      jasmine: {
        random: false
      }
    }
  })
9
dibbledeedoo

Mon problème était que les tests m'avaient mis dans une situation de compétition critique à cause d'une manière très stupide de configurer mes tests, mais je voulais tout de même le documenter ici, car j'avais du mal à trouver la réponse à mon problème sur Internet. 

Ce que j’avais fait en quelque sorte, c’était de déclarer deux fonctions beforeEach pour configurer mon test, et l’une des deux était asynchrone. Je me trouvais donc dans une situation critique, où elles étaient parfois en panne et en panne. 

Voici à quoi ressemblait mon test:

beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [ HomeComponent ]
    })
    .compileComponents();
  }));

  beforeEach(() => {
    fixture = TestBed.createComponent(HomeComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

Donc, pour résoudre ce problème, j’ai mis toute la configuration en un, synchrone avant chaque. 

  beforeEach(() => {
    TestBed.configureTestingModule({
      declarations: [HomeComponent]
    }).compileComponents();
    fixture = TestBed.createComponent(HomeComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

J'ai perdu trop de temps à essayer de comprendre cela, alors je le mets ici pour sauver quelqu'un d'autre. 

5
Oisin

Mon problème spécifique avec cette erreur était dû au fait que nous ne moquions pas les sous-composants du composant que je testais. Dans ce cas, j'avais un composant de page d'accueil avec deux sous-composants, ce qui nécessitait des déclarations pour les sous-composants, ce que je n'ai pas réussi à simuler.

En conséquence, les sous-composants avaient des dépendances réelles, ce qui entraînait l'échec des tests de manière non évidente (il semble que différents tests échouent de manière aléatoire, mais ce n'est pas le cas).

Se moquer comme suit marche plutôt bien dans ce cas:

@Component({
    selector: 'app-exercise',
    template: '<p>Mock Exercise Component</p>'
})
class MockExerciseComponent {
}

@Component({
    selector: 'app-user',
    template: '<p>Mock User Component</p>'
})
class MockUserComponent {
}

describe('HomepageComponent', () => {
    let component: HomepageComponent;
    let fixture: ComponentFixture<HomepageComponent>;

    beforeEach(async(() => {
        TestBed.configureTestingModule({
            // note you need to mock sub components!
            declarations: [HomepageComponent, MockExerciseComponent, MockUserComponent],
0
Richard