169 votes

Test de karma d'Angular 2 "component-name" n'est pas un élément connu

Dans l'AppComponent, j'utilise le composant nav dans le code HTML. L'interface utilisateur semble bien fonctionner. Aucune erreur lors de l'exécution de ng serve. et aucune erreur dans la console lorsque je regarde l'application.

Mais quand j'ai lancé Karma pour mon projet, il y a une erreur :

Failed: Template parse errors: 
'app-nav' is not a known element:
1. If 'app-nav' is an Angular component, then verify that it is part of this module.
2. If 'app-nav' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' to the '@NgModule.schemas' of this component to suppress this message.

Dans mon app.module.ts :

il y a :

import { NavComponent } from './nav/nav.component';

Il est également dans la partie déclarations de NgModule

@NgModule({
  declarations: [
    AppComponent,
    CafeComponent,
    ModalComponent,
    NavComponent,
    NewsFeedComponent
  ],
  imports: [
    BrowserModule,
    FormsModule,
    HttpModule,
    JsonpModule,
    ModalModule.forRoot(),
    ModalModule,
    NgbModule.forRoot(),
    BootstrapModalModule,
    AppRoutingModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})

J'utilise le NavComponent dans mon AppComponent

app.component.ts

import { Component, ViewContainerRef } from '@angular/core';
import { Overlay } from 'angular2-modal';
import { Modal } from 'angular2-modal/plugins/bootstrap';
import { NavComponent } from './nav/nav.component';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title = 'Angela';
}

app.component.html

<app-nav></app-nav>
<div class="container-fluid">
</div>

J'ai vu une question similaire, mais la réponse à cette question dit que nous devrions ajouter NgModule dans le composant nav qui a une exportation en elle, mais je reçois une erreur de compilation quand je fais cela.

Il y a aussi : app.component.spec.ts

import {NavComponent} from './nav/nav.component';
import { TestBed, async } from '@angular/core/testing';
import { AppComponent } from './app.component';

0 votes

Il vous manque probablement une importation dans votre fichier de spécification. Je suppose que le test de la spécification est sur app.spec.ts, donc vous voulez import { NavComponent } dans votre spec.ts

1 votes

C'est importé. Il me manquait la partie déclaration

1 votes

Importer et déclarer le composant personnalisé dans app.component.spec.ts a fonctionné pour moi, merci les gars !

251voto

Kim Kern Points 8727

Étant donné que dans les tests unitaires, vous souhaitez tester le composant en grande partie isolé des autres parties de votre application, Angular n'ajoutera pas par défaut les dépendances de votre module comme les composants, les services, etc. Vous devez donc le faire manuellement dans vos tests. Fondamentalement, vous avez deux options ici :

A) Déclarer le NavComponent original dans le test

describe('AppComponent', () => {
  beforeEach(async(() => {
      TestBed.configureTestingModule({
        declarations: [
          AppComponent,
          NavComponent
        ]
      }).compileComponents();
    }));

B) Simuler le composant NavComponent

describe('AppComponent', () => {
  beforeEach(async(() => {
      TestBed.configureTestingModule({
        declarations: [
          AppComponent,
          MockNavComponent
        ]
      }).compileComponents();
    }));

// it(...) test cases 

});

@Component({
  selector: 'app-nav',
  template: ''
})
class MockNavComponent {
}

Vous trouverez de plus amples informations dans le documentation officielle .

1 votes

Merci... Ça a marché pour moi !

2 votes

Merci pour ça. J'ai rencontré le problème de devoir importer de multiples composants et modules, à tel point qu'il serait beaucoup plus logique de n'importer que le module de gestion de l'environnement. AppModule dans la configuration de TestBed. Est-ce que vous recommandez de ne pas le faire ?

3 votes

@jonathan peut-être que le composant que vous avez déclaré a des dépendances qui lui sont propres ? Dans un test unitaire, il est préférable d'utiliser des mocks.

14voto

Adrian Points 119

Vous pouvez également utiliser NO_ERRORS_SCHEMA

describe('AppComponent', () => {
beforeEach(async(() => {
  TestBed.configureTestingModule({
    declarations: [
      AppComponent
    ],
    schemas: [NO_ERRORS_SCHEMA]
  }).compileComponents();
}));

https://2018.ng-conf.org/mocking-dependencies-angular/

3 votes

Y a-t-il des problèmes potentiels qui en découleront ? Cela semble être une solution pratique, mais y a-t-il des erreurs importantes qui seront éliminées par ce système ?

13 votes

C'est ce que le documents de test dites : " Le NO_ERRORS_SCHEMA empêche également le compilateur de vous signaler les composants et attributs manquants que vous avez omis par inadvertance ou mal orthographiés. Vous pourriez perdre des heures à chasser des bogues fantômes que le compilateur aurait détectés en un instant."

9 votes

Vous ne voulez certainement pas introduire un comportement implicite supplémentaire dans vos tests unitaires : l'utilisation de NO_ERRORS_SCHEMA vous encouragera à placer les dépendances dans la zone "grise" entre "mocked" et "pulled in". toute modification de ces dépendances peut potentiellement déclencher la rupture de tests unitaires apparemment sans rapport entre eux - ce qui n'est pas bon.

3voto

Kailas Points 672

Pour moi, l'importation du composant dans le parent a résolu le problème.

describe('AppComponent', () => {
  beforeEach(async(() => {
      TestBed.configureTestingModule({
        declarations: [
          AppComponent,
          NavComponent
        ]
      }).compileComponents();
    }));

Ajouter ceci dans spec of the parent où ce composant est utilisé.

1voto

GoTo Points 129

Une autre source de cette erreur est constituée par les tests du composant parent, app-Root, qui incluent la balise de ce composant, app-nav.

Même si le message concerne app-nav, le composant enfant, le correctif doit être ajouté dans les tests de app-Root, le composant parent.

La solution peut être un simulacre :

app.component.spec.ts :

@Component({selector: 'app-nav', template: ''})
    class NavComponentStub {
}

Ce qui se passe, c'est que vous créez le composant Root, avec ses tests, ils passent. Plus tard, vous ajoutez le composant enfant dans la balise du composant Root et maintenant vous devez mettre à jour les tests du composant Root même si vous avez juste ajouté une balise dans le modèle.

Le message ne précise pas non plus quel test a échoué et, d'après le message, vous pourriez être amené à croire qu'il s'agit des tests du composant enfant, alors qu'il s'agit en fait des tests du parent.

0voto

Yuvraj Patil Points 887

Étape 1 : Créer des stubs au début du fichier spec.

@Component({selector: 'app-nav', template: ''})
class NavComponent{}

Étape 2 : Ajouter les stubs dans les déclarations des composants.

TestBed.configureTestingModule({
  imports: [
    RouterTestingModule
  ],
  declarations: [
    AppComponent,
    NavComponent
  ],
}).compileComponents();

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X