Angular 2 Karma Test "ชื่อส่วนประกอบ" ไม่ใช่องค์ประกอบที่รู้จัก


110

ใน AppComponent ฉันกำลังใช้ส่วนประกอบ nav ในโค้ด HTML UI ดูดี ไม่มีข้อผิดพลาดเมื่อทำการเสิร์ฟ ng และไม่มีข้อผิดพลาดในคอนโซลเมื่อฉันดูแอป

แต่เมื่อฉันรัน 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 ในส่วนประกอบ 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

คำตอบ:


168

เนื่องจากในการทดสอบหน่วยคุณต้องการทดสอบส่วนประกอบที่แยกออกจากส่วนอื่น ๆ ของแอปพลิเคชันของคุณเป็นส่วนใหญ่ Angular จะไม่เพิ่มการอ้างอิงของโมดูลของคุณเช่นส่วนประกอบบริการ ฯลฯ โดยค่าเริ่มต้น ดังนั้นคุณต้องทำแบบทดสอบด้วยตนเอง โดยทั่วไปคุณมีสองตัวเลือกที่นี่:

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

1
ขอบคุณสำหรับสิ่งนี้. ฉันพบปัญหาในการต้องนำเข้าส่วนประกอบและโมดูลหลายรายการไปยังจุดที่เหมาะสมกว่าที่จะนำเข้าAppModuleในการกำหนดค่า TestBed คุณจะแนะนำให้ต่อต้านสิ่งนี้หรือไม่?
mcheah

@jonathan บางทีส่วนประกอบที่คุณประกาศว่ามีการอ้างอิงของตัวเอง? ในการทดสอบหน่วยควรใช้ mocks จะดีกว่า
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

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.