Nazwa komponentu w Angular 2 Karma Test nie jest znanym elementem


105

W AppComponent używam komponentu nav w kodzie HTML. Interfejs użytkownika wygląda dobrze. Brak błędów podczas serwowania. i żadnych błędów w konsoli, gdy patrzę na aplikację.

Ale kiedy uruchomiłem Karmę dla mojego projektu, pojawił się błąd:

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.

W moim app.module.ts :

jest:

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

Znajduje się również w części deklaracji NgModule

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

Używam NavComponentw moimAppComponent

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>

Widziałem podobne pytanie, ale odpowiedź na to pytanie mówi, że powinniśmy dodać NgModule do komponentu nawigacyjnego, który ma w tym eksport, ale otrzymuję błąd kompilacji, kiedy to robię.

Jest też: app.component.spec.ts

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

Prawdopodobnie brakuje importu w pliku specyfikacji. Zakładam, że test specyfikacji dotyczy aplikacji.spec.ts, więc będziesz chciał import { NavComponent }w swoich specyfikacjach
Z. Bagley

1
jest importowany. Brakowało mi części deklaracyjnej
Angela P

1
Importowanie i deklarowanie niestandardowego komponentu wewnątrz app.component.spec.ts zadziałało dla mnie, dzięki chłopaki!
ENDEESA

Odpowiedzi:


162

Ponieważ w testach jednostkowych chcesz przetestować komponent w większości odizolowany od innych części aplikacji, Angular nie doda domyślnie zależności twojego modułu, takich jak komponenty, usługi itp. Więc musisz to zrobić ręcznie w swoich testach. Zasadniczo masz tutaj dwie opcje:

A) W teście zadeklaruj oryginalny element NavComponent

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 {
}

Więcej informacji znajdziesz w oficjalnej dokumentacji .


Dzięki ... Pracował dla mnie !!
Hidayt Rahman

1
Dzięki za to. AppModuleNapotkałem problem konieczności importowania wielu komponentów i modułów do punktu, w którym o wiele bardziej sensowne jest po prostu zaimportowanie w konfiguracji TestBed. Czy odradzałbyś to?
mcheah

@jonathan może zadeklarowany przez Ciebie komponent ma własne zależności? W teście jednostkowym lepiej jest używać makiet.
Kim Kern

8

Możesz także użyć 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
czy są jakieś potencjalne problemy, które z tego wynikną? Wydaje się, że jest to wygodna poprawka, ale czy są jakieś ważne błędy, które zostaną przez to usunięte?
mcheah

8
Oto, co mówią dokumenty testujące : „NO_ERRORS_SCHEMA zapobiega również informowaniu przez kompilator o brakujących składnikach i atrybutach, które przypadkowo pominęłeś lub błędnie wpisałeś.
Kim Kern

5
zdecydowanie nie zamierzasz wprowadzać dodatkowego niejawnego zachowania do testów jednostkowych: użycie NO_ERRORS_SCHEMA zachęci Cię do umieszczenia zależności w „szarej” strefie między „wyszydzonymi” a „wciągniętymi”. wszelkie zmiany w tych zależnościach mogą potencjalnie spowodować przerwanie pozornie niepowiązanych testów jednostkowych - niedobrze
averasko

0

Dla mnie importowanie komponentu do rodzica rozwiązało problem.

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

Dodaj to w spec of the parentprzypadku użycia tego komponentu.


0

Jeszcze jeden powód jest taki, że w twoim przypadku testowym może być wiele .compileComponents()forbeforeEach()

np

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

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

0

Krok 1: Utwórz kody pośredniczące na początku pliku specyfikacji.

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

Krok 2: Dodaj kody pośredniczące w deklaracjach składników.

TestBed.configureTestingModule({
  imports: [
    RouterTestingModule
  ],
  declarations: [
    AppComponent,
    NavComponent
  ],
}).compileComponents();
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.