Angular 2 Karma Test'component-name'不是一个已知元素


105

在AppComponent中,我在HTML代码中使用了nav组件。用户界面看起来不错。服务时没有错误。当我查看应用程序时,控制台中没有错误。

但是,当我为我的项目运行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';

您可能会在规范文件中缺少导入。我假设的规范测试是app.spec.ts,所以你要import { NavComponent }在你的spec.ts
Z.巴格利

1
它是进口的。我缺少声明部分
Angela P

1
谢谢大家,在app.component.spec.ts中导入和声明自定义组件对我来说很有效!
ENDEESA,

Answers:


161

因为在单元测试中,您想测试大部分与应用程序其他部分隔离的组件,所以默认情况下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 '18

@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

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:在spec文件的开头创建存根。

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

步骤2:在组件的声明中添加存根。

TestBed.configureTestingModule({
  imports: [
    RouterTestingModule
  ],
  declarations: [
    AppComponent,
    NavComponent
  ],
}).compileComponents();
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.