【问题标题】:Angular 2 Karma Test 'component-name' is not a known elementAngular 2 Karma Test 'component-name' 不是已知元素
【发布时间】:2017-11-14 05:26:35
【问题描述】:

在 AppComponent 中,我在 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]
})

我在我的AppComponent 中使用NavComponent

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 上,所以你需要在你的 spec.ts 中 import { NavComponent }
  • 已导入。我错过了声明部分
  • 在 app.component.spec.ts 中导入和声明自定义组件对我有用,谢谢大家!

标签: javascript node.js angular typescript karma-jasmine


【解决方案1】:

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

您可以在official documentation 中找到更多信息。

【讨论】:

  • 谢谢...为我工作!!
  • 谢谢。我遇到了必须导入多个组件和模块的问题,以至于在 TestBed 配置中导入 AppModule 更有意义。你会反对这个吗?
  • @jonathan 也许你声明的组件有它自己的依赖关系?在单元测试中,最好使用模拟。
  • 是否有任何方法可以配置日志记录以显示测试名称或任何相关信息,以显示导致这些消息的规范?
  • 文档已移至angular.io/guide/…
【解决方案2】:

你也可以使用NO_ERRORS_SCHEMA

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

https://2018.ng-conf.org/mocking-dependencies-angular/

【讨论】:

  • 这会产生什么潜在的问题吗?这似乎是一个方便的修复,但是否有任何重要的错误会被此取消?
  • testing docs 是这么说的:“NO_ERRORS_SCHEMA 还会阻止编译器告诉您您无意中遗漏或拼写错误的缺失组件和属性。您可能会浪费数小时寻找编译器发现的幻像错误会在瞬间抓住。”
  • 你绝对不会在你的单元测试中引入额外的隐式行为:使用 NO_ERRORS_SCHEMA 会鼓励你将依赖项放入“mocked”和“pulled in”之间的“灰色”区域。对这些依赖项的任何更改都可能触发看似不相关的单元测试的中断——不好
【解决方案3】:

还有一个原因是你的测试用例中可以有多个.compileComponents() 对应beforeEach()

例如

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

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

【讨论】:

    【解决方案4】:

    对我来说,在父级中导入组件解决了这个问题。

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

    在使用该组件的spec of the parent 中添加。

    【讨论】:

      【解决方案5】:

      第 1 步:在规范文件的开头创建存根。

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

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

      TestBed.configureTestingModule({
        imports: [
          RouterTestingModule
        ],
        declarations: [
          AppComponent,
          NavComponent
        ],
      }).compileComponents();
      

      【讨论】:

        【解决方案6】:

        此错误的另一个来源是对父组件 app-root 的测试,其中包含该组件的标签 app-nav。

        即使消息是关于子组件 app-nav 的消息,也应该在父组件 app-root 的测试中添加修复。

        修复可以是模拟:

        app.component.spec.ts:

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

        发生的情况是您创建了根组件,通过它的测试,它们通过了。稍后您将子组件添加到根组件标签中,现在您必须更新根组件测试,即使您只是在模板中添加了标签。

        此外,消息并没有说明哪个测试失败,并且从消息中您可能会被引导相信这是子组件的测试,而实际上它们是父组件的测试。

        【讨论】:

          【解决方案7】:

          如果您创建了一个存根,但仍然得到相同的错误,这可能是因为 --watch 模式打开了。尝试停止它并再次运行。

          【讨论】:

            猜你喜欢
            • 2021-09-02
            • 2017-06-13
            • 2020-11-17
            • 1970-01-01
            • 1970-01-01
            • 2017-01-13
            • 2017-11-09
            • 1970-01-01
            • 2017-01-27
            相关资源
            最近更新 更多