Angular 2 Karma Test 'component-name'は既知の要素ではありません


104

AppComponentでは、HTMLコードでnavコンポーネントを使用しています。UIは正常に見えます。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>

同様の質問を見たことがありますが、その質問の答えは、エクスポートが含まれているnavコンポーネントにNgModuleを追加する必要があることを示していますが、そうするとコンパイルエラーが発生します。

またあります:app.component.spec.ts

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

specファイルにインポートがない可能性があります。仕様テストはapp.spec.tsで行うことを想定しているので、仕様に含める必要がimport { NavComponent }あります
Z. Bagley

1
インポートされます。宣言部分が欠けていました
アンジェラP

1
app.component.spec.ts内のカスタムコンポーネントのインポートと宣言がうまくいきました。
ENDEESA

回答:


160

単体テストではコンポーネントをアプリケーションの他の部分からほとんど分離してテストしたいので、Angularはデフォルトでコンポーネントやサービスなどのモジュールの依存関係を追加しません。したがって、テストでは手動で行う必要があります。基本的に、ここには2つのオプションがあります。

A)テストで元のNavComponentを宣言する

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

B)NavComponentをモックする

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

// it(...) test cases 

});

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

詳細については、公式ドキュメントをご覧ください。


ありがとう...私のために働いた!!
Hidayt Rahman、2018

1
これをありがとう。AppModuleTestBed構成でをインポートするだけの方がはるかに理にかなうところまで、複数のコンポーネントとモジュールをインポートする必要があるという問題に遭遇しました。これに対してお勧めしますか?
mcheah 2018

@jonathan宣言したコンポーネントには独自の依存関係がありますか?単体テストでは、モックを使用することをお勧めします。
Kim Kern、

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 2018年

8
これは何ですテストドキュメントは言う:「NO_ERRORS_SCHEMAも不足しているコンポーネントについてあなたを伝えるから、コンパイラを防ぎ、誤って省略またはスペルミスと属性あなたはコンパイラが瞬時にキャッチしたであろうファントムバグを追いかけて時間を無駄にすることができます。」
Kim Kern、

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();
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.