Angular 2 Karma Test 'tên-thành phần' không phải là một phần tử đã biết


104

Trong AppComponent, tôi đang sử dụng thành phần nav trong mã HTML. Giao diện người dùng trông ổn. Không có lỗi khi thực hiện ng giao bóng. và không có lỗi trong bảng điều khiển khi tôi xem ứng dụng.

Nhưng khi tôi chạy Karma cho dự án của mình, có một lỗi:

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.

Trong app.module.ts của tôi :

có:

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

Nó cũng nằm trong phần khai báo của NgModule

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

Tôi đang sử dụng NavComponenttrongAppComponent

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>

Tôi đã thấy một câu hỏi tương tự, nhưng câu trả lời trong câu hỏi đó nói rằng chúng ta nên thêm NgModule trong thành phần điều hướng có xuất trong đó, nhưng tôi gặp lỗi biên dịch khi làm điều đó.

Ngoài ra còn có: app.component.spec.ts

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

Có thể bạn đang thiếu một lần nhập trong tệp thông số kỹ thuật của mình. Tôi giả định các thử nghiệm spec là trên app.spec.ts, vì vậy bạn sẽ muốn import { NavComponent }ở spec.ts của bạn
Z. Bagley

1
nó được nhập khẩu. Tôi đã mất tích một phần tuyên bố
Angela P

1
Nhập và khai báo thành phần tùy chỉnh bên trong app.component.spec.ts đã hiệu quả với tôi, cảm ơn các bạn!
ENDEESA

Câu trả lời:


160

Bởi vì trong các bài kiểm tra đơn vị, bạn muốn kiểm tra thành phần chủ yếu được tách biệt khỏi các phần khác của ứng dụng, Angular sẽ không thêm các phụ thuộc vào mô-đun của bạn như các thành phần, dịch vụ, v.v. theo mặc định. Vì vậy, bạn cần làm điều đó theo cách thủ công trong các thử nghiệm của mình. Về cơ bản, bạn có hai tùy chọn ở đây:

A) Khai báo NavComponent ban đầu trong thử nghiệm

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

B) Chế nhạo NavComponent

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

// it(...) test cases 

});

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

Bạn sẽ tìm thấy thêm thông tin trong tài liệu chính thức .


Cảm ơn ... Đã làm việc cho tôi !!
Hidayt Rahman

1
Cảm ơn vì điều đó. Tôi đã gặp phải vấn đề phải nhập nhiều thành phần và mô-đun đến mức có ý nghĩa hơn nhiều nếu chỉ nhập AppModulevào cấu hình TestBed. Bạn có đề nghị chống lại điều này không?
mcheah,

@jonathan có thể thành phần bạn đã khai báo có các phụ thuộc của riêng nó? Trong một bài kiểm tra đơn vị, tốt hơn là sử dụng mô phỏng.
Kim Kern

8

Bạn cũng có thể dùng 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
có bất kỳ vấn đề tiềm ẩn nào sẽ phát sinh từ việc này không? Nó có vẻ giống như một bản sửa lỗi thuận tiện nhưng có bất kỳ lỗi quan trọng nào sẽ được giải quyết bằng cách này không?
mcheah

8
Đây là những gì tài liệu thử nghiệm nói: "NO_ERRORS_SCHEMA cũng ngăn trình biên dịch thông báo cho bạn về các thành phần và thuộc tính bị thiếu mà bạn đã vô tình bỏ qua hoặc viết sai chính tả. Bạn có thể lãng phí hàng giờ đồng hồ để đuổi theo các lỗi ma mà trình biên dịch đã bắt gặp ngay lập tức."
Kim Kern

5
bạn chắc chắn sẽ không đưa thêm hành vi ngầm vào các bài kiểm tra đơn vị của mình: sử dụng NO_ERRORS_SCHEMA sẽ khuyến khích bạn đưa các phần phụ thuộc vào vùng 'xám' giữa 'bị chế nhạo' và 'bị kéo vào'. bất kỳ thay đổi nào đối với những phụ thuộc đó có thể có khả năng kích hoạt việc phá vỡ các bài kiểm tra đơn vị dường như không liên quan - không tốt
trung bình

0

Đối với tôi nhập thành phần trong cha đã giải quyết vấn đề.

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

Thêm điều này vào spec of the parentnơi thành phần này được sử dụng.


0

Một lý do nữa là có thể có nhiều .compileComponents()cho beforeEach()trong trường hợp thử nghiệm của bạn

ví dụ

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

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

0

Bước 1: Tạo sơ khai ở đầu tệp đặc tả.

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

Bước 2: Thêm sơ khai trong khai báo của thành phần.

TestBed.configureTestingModule({
  imports: [
    RouterTestingModule
  ],
  declarations: [
    AppComponent,
    NavComponent
  ],
}).compileComponents();
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.