Angular 2 Karma Test "nome-componente" non è un elemento noto


105

In AppComponent, sto usando il componente nav nel codice HTML. L'interfaccia utente sembra a posto. Nessun errore durante l'esecuzione del servizio. e nessun errore nella console quando guardo l'app.

Ma quando ho eseguito Karma per il mio progetto, si è verificato un errore:

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.

Nella mia app.module.ts :

c'è:

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

È anche nella parte delle dichiarazioni di NgModule

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

Sto usando NavComponentnel mioAppComponent

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>

Ho visto una domanda simile, ma la risposta in quella domanda dice che dovremmo aggiungere NgModule nel componente nav che ha un'esportazione in quello, ma ricevo un errore di compilazione quando lo faccio.

C'è anche: app.component.spec.ts

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

Probabilmente ti manca un'importazione nel file delle specifiche. Suppongo che il test delle specifiche sia su app.spec.ts, quindi ti consigliamo di farlo import { NavComponent }nel tuo spec.ts
Z. Bagley,

1
è importato. Mi mancava la parte della dichiarazione
Angela P

1
L'importazione e la dichiarazione del componente personalizzato all'interno di app.component.spec.ts ha funzionato per me, grazie ragazzi!
ENDEESA

Risposte:


161

Poiché negli unit test vuoi testare il componente per lo più isolato da altre parti della tua applicazione, Angular non aggiungerà le dipendenze del tuo modulo come componenti, servizi, ecc. Per impostazione predefinita. Quindi devi farlo manualmente nei tuoi test. Fondamentalmente, hai due opzioni qui:

A) Dichiarare il NavComponent originale nel test

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

B) Mock the NavComponent

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

// it(...) test cases 

});

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

Troverai maggiori informazioni nella documentazione ufficiale .


Grazie ... ha funzionato per me !!
Hidayt Rahman

1
Grazie per questo. Mi sono imbattuto nel problema di dover importare più componenti e moduli al punto in cui ha molto più senso importare semplicemente il file AppModulenella configurazione TestBed. Consiglieresti contro questo?
mcheah

@jonathan forse il componente che hai dichiarato ha delle dipendenze proprie? In uno unit test, è meglio usare i mock.
Kim Kern

8

Puoi anche usare 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
ci sono potenziali problemi che ne deriveranno? Sembra una soluzione conveniente, ma ci sono errori importanti che verranno annullati da questo?
mcheah

8
Questo è ciò che dicono i documenti di test : "NO_ERRORS_SCHEMA impedisce anche al compilatore di informarti sui componenti mancanti e sugli attributi che hai omesso inavvertitamente o con errori di ortografia. Potresti sprecare ore a caccia di bug fantasma che il compilatore avrebbe individuato in un istante."
Kim Kern

5
sicuramente non vorrai introdurre comportamenti impliciti extra nei tuoi unit test: l'uso di NO_ERRORS_SCHEMA ti incoraggerà a mettere le dipendenze nella zona "grigia" tra "mocked" e "pull in". qualsiasi modifica a tali dipendenze può potenzialmente innescare la rottura di unit test apparentemente non correlati - non va bene
averasko

0

Per me l'importazione del componente nel genitore ha risolto il problema.

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

Aggiungi questo nel spec of the parentpunto in cui viene utilizzato questo componente.


0

Un motivo in più è che nel tuo caso di test possono esserci più .compileComponents()perbeforeEach()

per es

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

beforeEach(() => {
  TestBed.configureTestingModule({
    imports: [HttpClientModule],
    declarations: [Test1Component],
    providers: [HttpErrorHandlerService]
  }).compileComponents();
});

0

Passaggio 1: crea stub all'inizio del file delle specifiche.

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

Passaggio 2: aggiungi stub nelle dichiarazioni del componente.

TestBed.configureTestingModule({
  imports: [
    RouterTestingModule
  ],
  declarations: [
    AppComponent,
    NavComponent
  ],
}).compileComponents();
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.