Erreur Angular Karma Jasmine: état illégal: impossible de charger le résumé de la directive

98

Je développe un dépôt github (avec angular 7 et angular-cli), et j'ai quelques tests avec Karma et Jasmine travaillant dans la branche master.

Maintenant, j'essaie d'ajouter une fonction de chargement paresseux, le fait est que les tests qui auparavant passaient, maintenant ils ne le font pas. C'est drôle car seuls les tests du module de chargement paresseux échouent ...

Voici le code et l'erreur:

import {async, TestBed} from '@angular/core/testing';
import {APP_BASE_HREF} from '@angular/common';
import {AppModule} from '../../app.module';
import {HeroDetailComponent} from './hero-detail.component';

describe('HeroDetailComponent', () => {
  beforeEach(async(() => {
    TestBed.configureTestingModule({
      imports: [AppModule
      ],
      providers: [
        {provide: APP_BASE_HREF, useValue: '/'}
      ],
    }).compileComponents();
  }));

  it('should create hero detail component', (() => {
    const fixture = TestBed.createComponent(HeroDetailComponent);
    const component = fixture.debugElement.componentInstance;
    expect(component).toBeTruthy();
  }));
});

L'erreur est la suivante:

Chrome 58.0.3029 (Mac OS X 10.12.6) HeroDetailComponent should create hero detail component FAILED
    Error: Illegal state: Could not load the summary for directive HeroDetailComponent.
        at syntaxError Users/ismael.ramos.silvan/WebstormProjects/angular4-example-app/~/@angular/compiler/@angular/compiler.es5.js:1690:22)
        at CompileMetadataResolver.getDirectiveSummary Users/ismael.ramos.silvan/WebstormProjects/angular4-example-app/~/@angular/compiler/@angular/compiler.es5.js:15272:1)
        at JitCompiler.getComponentFactory Users/ismael.ramos.silvan/WebstormProjects/angular4-example-app/~/@angular/compiler/@angular/compiler.es5.js:26733:26)
        at TestingCompilerImpl.getComponentFactory Users/ismael.ramos.silvan/WebstormProjects/angular4-example-app/~/@angular/compiler/@angular/compiler/testing.es5.js:484:1)
        at TestBed.createComponent Users/ismael.ramos.silvan/WebstormProjects/angular4-example-app/~/@angular/core/@angular/core/testing.es5.js:874:1)
        at Function.TestBed.createComponent Users/ismael.ramos.silvan/WebstormProjects/angular4-example-app/~/@angular/core/@angular/core/testing.es5.js:652:1)
        at UserContext.it Users/ismael.ramos.silvan/WebstormProjects/angular4-example-app/src/app/heroes/hero-detail/hero-detail.component.spec.ts:18:29)
        at ZoneDelegate.webpackJsonp.../../../../zone.js/dist/zone.js.ZoneDelegate.invoke Users/ismael.ramos.silvan/WebstormProjects/angular4-example-app/~/zone.js/dist/zone.js:391:1)
        at ProxyZoneSpec.onInvoke Users/ismael.ramos.silvan/WebstormProjects/angular4-example-app/~/zone.js/dist/proxy.js:79:1)
        at ZoneDelegate.webpackJsonp.../../../../zone.js/dist/zone.js.ZoneDelegate.invoke Users/ismael.ramos.silvan/WebstormProjects/angular4-example-app/~/zone.js/dist/zone.js:390:1)

Vous pouvez voir l'ensemble du projet, pour plus de détails si vous en avez besoin.

MISE À JOUR: déclaration ajoutée comme celle-ci:

beforeEach(async(() => {
    TestBed.configureTestingModule({
      imports: [
        AppModule
      ],
      declarations: [HeroDetailComponent],
      providers: [
        {provide: APP_BASE_HREF, useValue: '/'}
      ],
    }).compileComponents();
  }));

Maintenant, de nouvelles erreurs apparaissent:

The pipe 'translate' could not be found ("<h1 class="section-title">{{[ERROR ->]'heroDetail' | translate}}</h1>
    <md-progress-spinner *ngIf="!hero"
                         class="progre"): ng:///DynamicTestModule/HeroDetailComponent.html@0:28
    Can't bind to 'color' since it isn't a known property of 'md-progress-spinner'.

Et plus ... c'est comme toutes les directives et tous les composants d'un matériau angulaire, et le tube translate de ngx-translate / core ne semble pas être inclus ...

MISE À JOUR: SOLUTION FINALE

Le problème était que HeroesModule n'a été importé nulle part. Cela fonctionne, car HeroesModule déclare HeroDetailComponent, qui était le problème initial :

import {async, TestBed} from '@angular/core/testing';
import {APP_BASE_HREF} from '@angular/common';
import {AppModule} from '../../app.module';
import {HeroDetailComponent} from './hero-detail.component';
import {HeroesModule} from '../heroes.module';

describe('HeroDetailComponent', () => {
  beforeEach(async(() => {
    TestBed.configureTestingModule({
      imports: [
        AppModule,
        HeroesModule
      ],
      providers: [
        {provide: APP_BASE_HREF, useValue: '/'}
      ],
    }).compileComponents();
  }));

  it('should create hero detail component', (() => {
    const fixture = TestBed.createComponent(HeroDetailComponent);
    const component = fixture.debugElement.componentInstance;
    expect(component).toBeTruthy();
  }));
});
ismaestro
la source
1
Vous n'avez pas besoin de déclarer le composant pour le tester, il vous suffit de configurer le banc de test légèrement différemment: github.com/angular/angular/issues/17477#issuecomment-510397690
Stevanicus

Réponses:

179

Vous avez passé HeroDetailComponentà TestBed.createComponent()sans déclarer le composant au préalable:

TestBed.configureTestingModule({
  imports: [AppModule,
     CommonModule,
     FormsModule,
     SharedModule,
     HeroRoutingModule,
     ReactiveFormsModule
  ],
  providers: [
    {provide: APP_BASE_HREF, useValue: '/'}
  ],
  declarations: [HeroDetailComponent]
}).compileComponents();

J'espère que ça aide.


Mise à jour pour les erreurs suivantes dans votre test: Ajout de quelques importations supplémentaires (prenez simplement votre HeroModule comme plan, car c'est essentiellement ce que vous voulez importer et fournir).

Lexith
la source
Si j'ajoute cette déclaration, d'autres erreurs apparaissent. J'ai mis à jour les informations, vous pouvez le voir ci-dessus.
ismaestro
1
Eh bien, mais c'est ainsi que vous vous débarrassez de cette erreur. Les erreurs suivantes peuvent être un autre problème avec votre configuration de test.
lexith
Quelle erreur vient ensuite?
lexith
Le tube 'translate' est introuvable ("<h1 class =" section-title "> {{[ERROR ->] 'heroDetail' | translate}} </h1> <md-progress-spinner * ngIf ="! hero "class =" progre "): ng: ///DynamicTestModule/HeroDetailComponent.html@0: 28 Impossible de se lier à 'color' car ce n'est pas une propriété connue de 'md-progress-spinner'.
ismaestro
Et n'oubliez pas que cela se produit parce que c'est un module de chargement paresseux. Parce que les autres tests que j'ai n'échouent pas ...
ismaestro
8

Il vous manque les déclarations, vous devez ajouter la classe testée dans les déclarations.

declarations: [component]
Akash Yellappa
la source
Dans mon cas, j'ai copié la configuration de TestBed d'un composant vers le nouveau et, ensuite, je n'ai pas inclus le composant testé.
Tonatio
2

Ce type d'erreur s'est produit en raison d'un composant d'ajout manquant dans les déclarations et services dans le fournisseur de configuration TestBed.

beforeEach(() => {
    TestBed.configureTestingModule({
      imports: [RouterTestingModule.withRoutes([
        { path: 'home', component: DummyComponent },
        { path: 'patients/find', component: DummyComponent }
      ])],
      declarations: [RoutingComponent, DummyComponent,BreadcrumbComponent],
      providers : [BreadCrumbService]
    });
Vijay Barot
la source
2

Mon collègue et moi avons eu ce problème, mais le correctif était bien différent de toute autre chose sur Internet.

Nous utilisons Visual Studio Code et les noms de dossier ne sont pas sensibles à la casse. Pour cette raison, nous avons demandé à tout le monde d'utiliser une convention de dénomination en minuscules, mais finalement un nom en majuscule est entré dans le contrôle de code source. Nous l'avons renommé, de manière détournée, et tout allait bien.

Un mois plus tard, mon collègue a commencé à obtenir un test unitaire spécifique pour rompre avec ce message d'erreur. Seul son ordinateur cassait lors de ce test. Nous avons littéralement commenté tout le code qui pourrait effectuer le test et nous avons toujours l'erreur. Enfin, j'ai recherché globalement la classe et nous nous sommes rendu compte que le nom du dossier était revenu au nom en majuscules. Nous l'avons renommé en minuscules, sans qu'aucune modification en attente ne soit reconnue, puis-je ajouter ..., et le test a fonctionné.

Que ce soit une leçon pour suivre les guides de style. :)

Pour plus de clarté, le correctif était similaire à la modification du nom du dossier FOOen foo.

christo8989
la source
1

vous devez importer le composant HeroDetailComponent de la bonne manière. Notez que même la casse des lettres est importante dans les chemins. ie ('@ angular / forms' est correct, MAIS '@ angular / Forms' ne l'est pas.

sami
la source
1

Pour ceux qui rencontrent toujours des problèmes avec cela, j'ai lu un problème github séparé qui traitait des modifications apportées par l'équipe Angular à la fonction de rappel beforeEach.

Voici ce que j'ai fait:

beforeAll(async(() => {
    TestBed.configureTestingModule({
        declarations: [BannerNotificationComponent]
    }).compileComponents()

    fixture = TestBed.createComponent(BannerNotificationComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
}));

L'utilisation de beforeAll résout le problème. J'espère que cela aide les autres car il m'a fallu environ une journée pour résoudre ce bug obscur.

Adam P
la source
0

Si vous souhaitez tester un composant sans le compiler, vous pouvez le déclarer en tant que fournisseur:

beforeEach(() => {
  TestBed.configureTestingModule({
    // provide the component-under-test and dependent service
    providers: [
      WelcomeComponent,
      { provide: UserService, useClass: MockUserService }
    ]
  });
  // inject both the component and the dependent service.
  comp = TestBed.get(WelcomeComponent);
  userService = TestBed.get(UserService);
});

Voir: https://angular.io/guide/testing#component-test-basics

Stevanicus
la source