Кутовий тест Карми 2 "Ім'я компонента" не є відомим елементом


105

У AppComponent я використовую компонент nav у HTML-коді. Інтерфейс виглядає добре. Немає помилок при виконанні подачі. і жодних помилок у консолі під час перегляду програми.

Але коли я керував Кармою для свого проекту, виникла помилка:

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.

У моєму app.module.ts :

існує:

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

Він також є в частині декларацій NgModule

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

Я використовую NavComponentв моєму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>

Я бачив подібне запитання, але відповідь на це питання говорить, що ми повинні додати NgModule в компонент nav, який має експорт у цьому, але я отримую помилку компіляції, коли це роблю.

Також є: app.component.spec.ts

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

Ймовірно, вам не вистачає імпорту у вашому файлі специфікації Я припускаю, що тест на специфікацію є на app.spec.ts, тож вам захочеться import { NavComponent }у своїх spec.ts
Z. Bagley

1
це імпорт. Я пропустив деклараційну частину
Angela P

1
Імпорт і декларування користувацького компонента всередині app.component.spec.ts працював на мене, дякую хлопці!
ENDEESA

Відповіді:


161

Оскільки в одиничних тестах ви хочете протестувати компонент, здебільшого ізольований від інших частин програми, Angular за замовчуванням не додасть залежності вашого модуля, як компоненти, послуги тощо. Тому вам потрібно зробити це вручну під час тестів. В основному, у вас є два варіанти тут:

А) Зазначте вихідний NavComponent у тесті

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

В) Знущайтеся над NavComponent

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

// it(...) test cases 

});

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

Більше інформації ви знайдете в офіційній документації .


Дякую ... Працювали для мене !!
Хідайт Рахман

1
Дякую за це Я зіткнувся з проблемою необхідності імпорту декількох компонентів і модулів до того моменту, коли має сенс просто імпортувати AppModuleв конфігурацію TestBed. Чи рекомендуєте ви проти цього?
mcheah

@jonathan, можливо, компонент, який ви заявили, має власні залежності? В одиничному тесті краще використовувати макети.
Кім Керн

8

Ви також можете використовувати NO_ERRORS_SCHEMA

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

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


3
Чи можливі проблеми, які виникатимуть із цього? Це здається зручним виправленням, але чи є важливі помилки, які будуть усунені цим?
mcheah

8
Про це говорять документи тестування : "NO_ERRORS_SCHEMA також заважає компілятору повідомити вам про відсутні компоненти та атрибути, які ви ненавмисно опущені або неправильно написані. Ви можете витрачати години на переслідування фантомних помилок, які компілятор зачепив би за мить."
Кім Керн

5
Ви точно не хочете вводити надмірну неявну поведінку у ваші тестові одиниці: використання NO_ERRORS_SCHEMA спонукає вас ставити залежності в 'сіру' зону між 'знущаються' та 'втягнуті'. будь-які зміни цих залежностей можуть потенційно спричинити зрив, здавалося б, не пов'язаних між собою одиничних тестів - нічого хорошого
averasko

0

Для мене імпорт компонента у батьківській програмі вирішив проблему.

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

Додайте його spec of the parentтуди, де використовується цей компонент.


0

Ще одна причина полягає в тому , що там може бути кілька .compileComponents()для beforeEach()вашої тесту

напр

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

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

0

Крок 1: Створіть заглушки на початку файла специфікації.

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

Крок 2. Додайте заглушки в декларації компонента.

TestBed.configureTestingModule({
  imports: [
    RouterTestingModule
  ],
  declarations: [
    AppComponent,
    NavComponent
  ],
}).compileComponents();
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.