Angular 2 Karma Test 'имя-компонента' не является известным элементом


106

В AppComponent я использую компонент nav в HTML-коде. Пользовательский интерфейс выглядит нормально. Нет ошибок при выполнении ng serve. и никаких ошибок в консоли, когда я смотрю на приложение.

Но когда я запустил Karma для своего проекта, возникла ошибка:

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 в компонент навигации, в котором есть экспорт, но при этом я получаю ошибку компиляции.

Также есть: 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
З. Бэгли,

1
это импортировано. Мне не хватало декларации
Анджела П.

1
Импорт и объявление пользовательского компонента внутри app.component.spec.ts сработали для меня, спасибо, ребята!
ENDEESA

Ответы:


162

Поскольку в модульных тестах вы хотите протестировать компонент, в основном изолированный от других частей вашего приложения, Angular не будет добавлять зависимости вашего модуля, такие как компоненты, службы и т. Д. По умолчанию. Так что вам нужно сделать это вручную в ваших тестах. По сути, у вас есть два варианта:

A) Объявите исходный компонент 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-dependencies-angular/


3
есть ли какие-то потенциальные проблемы, которые могут возникнуть в связи с этим? Кажется, удобное исправление, но есть ли какие-то важные ошибки, которые будут устранены этим?
mcheah 01

8
Вот что говорится в документации по тестированию : «NO_ERRORS_SCHEMA также не позволяет компилятору сообщать вам о недостающих компонентах и ​​атрибутах, которые вы случайно пропустили или написали с ошибками. Вы можете потратить часы на поиск фантомных ошибок, которые компилятор обнаружил бы в одно мгновение».
Ким Керн

5
вы определенно не хотите вводить лишнее неявное поведение в свои модульные тесты: использование NO_ERRORS_SCHEMA побудит вас поместить зависимости в «серую» зону между «высмеянным» и «втянутым». любые изменения в этих зависимостях могут потенциально вызвать нарушение работы, казалось бы, несвязанных модульных тестов - бесполезно
авераско

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.