Angular 2 Jasmine测试,加载app.component.ts中的所有组件?

时间:2017-06-28 19:48:28

标签: angular jasmine karma-jasmine angular-cli

我正在开发一个小型测试应用,以便更好地学习Angular 2中的Angular 2和单元测试。来自反应 - Jest背景;在app.component.ts中包含所有组件会感觉很奇怪。

这就是我目前所拥有的组件层次结构:

App.Component> Layout.Component> Header.Component> Nav.Component

当我运行npm测试时,我收到错误

  

主报头'不是一个已知元素:

当我通过在App.Component.spec.ts中导入并声明绑定到该选择器的组件来修复此问题时,我会在下一个组件/选择器内联时得到相同的错误。

这是一个包含许多组件的大型应用程序;我可以看到App.Component的测试变得庞大且无法维护。经过几次谷歌搜索,产生了AngularJS和Angular RC.X的结果......我已经走到了尽头。我的直觉告诉我有些事情是错的,这不能成为Angular 2中的测试方式......但我可能错了!

2 个答案:

答案 0 :(得分:1)

请提供有关在Angular上生成项目的方式的更多详细信息。我建议您使用Angular CLI生成项目/组件/管道/服务,因为它会代表您为每个生成spec.ts文件,并且还会将组件链接到模块。

然后,将Angular的测试类视为一个空的测试平台,您必须重新创建组件的结构才能进行测试。在实际的应用程序中,所有绑定都是在模块内部进行的,但这不是测试的情况,您必须导入并声明组件的所有组件,以便测试框架能够构建并测试它。

在您提供的结构中,您将为每个组件创建一个测试类,如:

Nav.Component.spec.ts
Header.Component.spec.ts
Layout.Component.spec.ts
App.Component.spec.ts

考虑到层次结构,每个人都会做类似的事情:

<强> Nav.Component.spec.ts

 import { NavComponent } from './your path to component';
 ...
 beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [ NavComponent  ]
    })
    .compileComponents();
 }));

<强> Header.Component.spec.ts

 import { NavComponent } from './your path to component';
 import { HeaderComponent } from './your path to component';
 ...
 beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [ NavComponent , HeaderComponent ]
    })
    .compileComponents();
 }));

<强> Layout.Component.spec.ts

 import { NavComponent } from './your path to component';
 import { HeaderComponent } from './your path to component';
 import { LayoutComponent } from './your path to component';
 ...
 beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [ NavComponent , HeaderComponent , LayoutComponent ]
    })
    .compileComponents();
 }));

<强> App.Component.spec.ts

 import { NavComponent } from './your path to component';
 import { HeaderComponent } from './your path to component';
 import { LayoutComponent } from './your path to component';
 import { AppComponent } from './your path to component';
 ...
 beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [ NavComponent , HeaderComponent , LayoutComponent, AppComponent  ]
    })
    .compileComponents();
 }));

如果你这样做,应该工作。整个想法是使用它所使用的所有元素来重构测试每个元素以便工作。 如果某些内容不够清晰或不起作用,请提供更多详细信息。

我提供的导入每个组件的示例是使其与您所呈现的未在模块上链接的组件结构一起工作的方法。但是,正如我告诉你的那样,这不是它打算建造的方式。 如果使用Angular CLI生成,则可以执行以下操作: 生成您的模块,如:

ng generate module layout -m app

这将生成您的布局模块并将其导入app.module 然后以相同的方式生成所有组件:

ng generate component layout -m layout
ng generate component header -m layout
ng generate component nav -m layout

这将生成所有组件,将每个组件导入layout.module,该版本已导入app.module。 这样你就不必再导入任何东西,你的测试就可以了。

以下是每个元素的样子:

<强> app.module

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { AppComponent } from './app.component';
import { LayoutModule } from './layout/layout.module';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    LayoutModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

布局模块

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { LayoutComponent } from './layout.component';
import { HeaderComponent } from '../header/header.component';
import { NavComponent } from '../nav/nav.component';

@NgModule({
  imports: [
    CommonModule
  ],
  declarations: [LayoutComponent, HeaderComponent, NavComponent]
})
export class LayoutModule { }

布局组件

import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'app-layout',
  templateUrl: './layout.component.html',
  styleUrls: ['./layout.component.css']
})
export class LayoutComponent implements OnInit {

  constructor() { }

  ngOnInit() {
  }

}

标题组件

import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'app-header',
  templateUrl: './header.component.html',
  styleUrls: ['./header.component.css']
})
export class HeaderComponent implements OnInit {

  constructor() { }

  ngOnInit() {
  }

}

导航组件

import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'app-nav',
  templateUrl: './nav.component.html',
  styleUrls: ['./nav.component.css']
})
export class NavComponent implements OnInit {

  constructor() { }

  ngOnInit() {
  }

}

答案 1 :(得分:0)

如果在一个模块中分组了几个组件,则可以导入模块进行测试,而不必声明每个组件。

beforeEach(async(() => {
  TestBed.configureTestingModule({
    declarations: [AppComponent],
    imports: [SomeModule]
  }).compileComponents();
}));