Angular 2 Karma Test 'Komponentenname' ist kein bekanntes Element


104

In der AppComponent verwende ich die nav-Komponente im HTML-Code. Die Benutzeroberfläche sieht gut aus. Keine Fehler beim Aufschlag. und keine Fehler in der Konsole, wenn ich mir die App ansehe.

Aber als ich Karma für mein Projekt ausgeführt habe, ist ein Fehler aufgetreten:

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.

In meiner app.module.ts :

es gibt:

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

Es ist auch in den Deklarationen Teil von NgModule

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

Ich benutze das NavComponentin meinemAppComponent

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>

Ich habe eine ähnliche Frage gesehen, aber die Antwort in dieser Frage besagt, dass wir NgModule in die Navigationskomponente einfügen sollten, die einen Export enthält, aber ich erhalte dabei einen Kompilierungsfehler.

Es gibt auch: app.component.spec.ts

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

Sie vermissen wahrscheinlich einen Import in Ihrer Spezifikationsdatei. Ich gehe davon aus, dass der Spezifikationstest auf app.spec.ts ist, also möchten Sie import { NavComponent }in Ihren spec.ts
Z. Bagley

1
es ist importiert. Mir fehlte der Deklarationsteil
Angela P

1
Das Importieren und Deklarieren der benutzerdefinierten Komponente in app.component.spec.ts hat bei mir funktioniert, danke Jungs!
ENDEESA

Antworten:


159

Da Sie in Komponententests die Komponente testen möchten, die größtenteils von anderen Teilen Ihrer Anwendung isoliert ist, fügt Angular die Abhängigkeiten Ihres Moduls wie Komponenten, Dienste usw. standardmäßig nicht hinzu. Sie müssen dies also manuell in Ihren Tests tun. Grundsätzlich haben Sie hier zwei Möglichkeiten:

A) Deklarieren Sie die ursprüngliche NavComponent im Test

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

B) Verspotten Sie die NavComponent

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

// it(...) test cases 

});

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

Weitere Informationen finden Sie in der offiziellen Dokumentation .


Danke ... Hat für mich gearbeitet !!
Hidayt Rahman

1
Danke dafür. Ich bin auf das Problem gestoßen, mehrere Komponenten und Module so weit importieren zu müssen, dass es weitaus sinnvoller ist, nur die AppModulein der TestBed-Konfiguration zu importieren . Würden Sie dagegen empfehlen?
mcheah

@ Jonathan Vielleicht hat die von Ihnen deklarierte Komponente eigene Abhängigkeiten? In einem Unit-Test ist es besser, Mocks zu verwenden.
Kim Kern

8

Sie können auch verwenden 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
Gibt es potenzielle Probleme, die sich daraus ergeben werden? Es scheint eine bequeme Lösung zu sein, aber gibt es wichtige Fehler, die dadurch behoben werden?
mcheah

8
Dies ist , was die Prüfung docs sagen: „Der NO_ERRORS_SCHEMA verhindert auch die Compiler von Ihnen über die fehlenden Komponenten zu erzählen und Attribute , die Sie versehentlich oder falsch geschrieben ausgelassen Sie Stunden verschwenden könnten Phantom Bugs zu jagen , dass der Compiler in einem Augenblick gefangen haben würde.“
Kim Kern

5
Sie werden definitiv kein zusätzliches implizites Verhalten in Ihre Komponententests einführen: Wenn Sie NO_ERRORS_SCHEMA verwenden, werden Sie dazu ermutigt, Abhängigkeiten in die "graue" Zone zwischen "verspottet" und "eingezogen" zu setzen. Änderungen an diesen Abhängigkeiten können möglicherweise dazu führen, dass scheinbar nicht zusammenhängende
Komponententests abgebrochen

0

Für mich hat das Importieren der Komponente in das übergeordnete Element das Problem behoben.

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

Fügen Sie dies dort hinzu, spec of the parentwo diese Komponente verwendet wird.


0

Ein weiterer Grund ist , dass es können mehrere sein .compileComponents()für beforeEach()in Ihrem Testfall

für zB

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

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

0

Schritt 1: Erstellen Sie Stubs am Anfang der Spezifikationsdatei.

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

Schritt 2: Fügen Sie Stubs in die Deklarationen der Komponente ein.

TestBed.configureTestingModule({
  imports: [
    RouterTestingModule
  ],
  declarations: [
    AppComponent,
    NavComponent
  ],
}).compileComponents();
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.