运行 "ng test" 时 Karma 中的元素未知错误
Element not known error in Karma when ran "ng test"
当我 运行
时,我的项目 运行 运行良好
ng serve
但是当我 运行 使用
一个简单的 "tobeTruthy()" 测试用例时它显示多个错误
ng test
HTML 文件
<ngx-spinner bdColor="rgba(51,51,51,0.8)" size="medium" color="#fff" type="ball-scale-multiple">
<p style="font-size: 20px; color: white">Loading...</p>
</ngx-spinner>
<div *ngIf="isAuthenticated" class="container-fluid">
<app-app-menu></app-app-menu>
<router-outlet></router-outlet>
</div>
app.component.ts
import { Router } from '@angular/router';
import { Component, OnInit } from '@angular/core';
import { Store } from '@ngrx/store';
import { map } from 'rxjs/operators';
import { AppState } from './app.reducer';
import { UserState } from './core/store/core.state';
import * as CoreActions from './core/store/core.actions';
import { Globals } from './shared/globals';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent implements OnInit {
datetime = new Date();
title = 'curemd-x';
isAuthenticated = false;
constructor(private store: Store<AppState>, private router: Router,
private globals: Globals) {}
...
...
业力错误
"Failed: Template parse errors:
'ngx-spinner' is not a known element:
1. If 'ngx-spinner' is an Angular component, then verify that it is part of this module.
2. If 'ngx-spinner' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' to the '@NgModule.schemas' of this component to suppress this message. ("[ERROR ->]<ngx-spinner bdColor="rgba(51,51,51,0.8)" size="medium" color="#fff" type="ball-scale-multiple">
<p"): ng:///DynamicTestModule/AppComponent.html@0:0
'app-app-menu' is not a known element:
1. If 'app-app-menu' is an Angular component, then verify that it is part of this module.
2. If 'app-app-menu' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' to the '@NgModule.schemas' of this component to suppress this message. ("
</ngx-spinner>
<div *ngIf="isAuthenticated" class="container-fluid">
[ERROR ->]<app-app-menu></app-app-menu>
<router-outlet></router-outlet>
</div>
"): ng:///DynamicTestModule/AppComponent.html@4:2
我也尝试包含 "CUSTOM_ELEMENTS_SCHEMA" 但没有成功。
"app-app-menu" 是核心模块中存在的组件,核心模块在 app.module
中导入
app.module.ts
declarations: [
AppComponent,
FirstOrDefaultPipe
],
imports: [
RouterModule,
BrowserModule,
HttpClientModule,
PatientModule,
StoreModule.forRoot(AppReducers),
EffectsModule.forRoot([]),
CoreModule,
NgxSpinnerModule,
BrowserAnimationsModule,
DropDownsModule
],
providers: [Globals],
bootstrap: [AppComponent],
schemas: [CUSTOM_ELEMENTS_SCHEMA]
})
export class AppModule { }
如何才能运行 应用模块实例的成功测试用例?
Angular 开发人员经常对此感到困惑。当您 运行 ng test
、karma 和 jasmine 运行s angular 模块定义在 .spec.ts
文件中时。它根本不查看您的正常代码。所以无论你输入 app.module.ts
对你的测试模块没有任何影响。您可以做两件事。
将CUSTOM_ELEMENTS_SCHEMA
添加到测试模块
在 app.component.spec.ts
内执行以下操作
TestBed.configureTestingModule({
declarations: [
AppComponent
],
schemas: [CUSTOM_ELEMENTS_SCHEMA]
}).compileComponents();
这将解决您现在遇到的错误。但是,您可能会遇到其他人,因为我看到您向 AppComponent
注入了一些服务,这让我们接下来可以做一些事情
在测试模块中导入 AppModule
。
您可以按如下方式在 TestBed
中导入 AppModule
。这样做的目的是确保您的测试始终具有它们需要定义的内容。如果您将另一个组件添加到 AppModule
并在 AppComponent
中使用它,它也将在测试中可用。此外,您不需要添加 CUSTOM_ELEMENTS_SCHEMA
。
但是,您应该知道,这将导入并创建您在 app.component
中使用的任何第 3 方 component/services。有人会争辩说这有悖于单元测试的本质。您仍然可以以某种方式模拟这些服务,但它们将被渲染。此外,在 angular 应用程序中,当测试导入 RouterModule
的模块时,将使用 RouterTestingModule
代替。在测试中使用 RouterModule
可能会搞乱你的测试,因为这些测试 运行 在无头浏览器上和 RouterModule
可能会导致 URL 更改。
TestBed.configureTestingModule({
imports: [
AppModule
],
}).compileComponents();
虽然是正确的,意味着它有效地解决了问题,但请注意以下几点:
- 使用
CUSTOM_ELEMENTS_SCHEMA
或NO_ERRORS_SCHEMA
可能会导致“误吞”。如 official doc 中所述,请勿过度使用它们。
- importing
AppModule
意味着您正在编写集成测试。通常,最好编写一个独立的单元测试。
因此,恕我直言,最好的解决方案是存根不需要的组件,如 official doc 中所述。基本上,您将使用相同的选择器创建一个空组件。如果你有很多组件,这可能会很乏味,但我相信这是目前的最佳做法。
当我 运行
时,我的项目 运行 运行良好ng serve
但是当我 运行 使用
一个简单的 "tobeTruthy()" 测试用例时它显示多个错误ng test
HTML 文件
<ngx-spinner bdColor="rgba(51,51,51,0.8)" size="medium" color="#fff" type="ball-scale-multiple">
<p style="font-size: 20px; color: white">Loading...</p>
</ngx-spinner>
<div *ngIf="isAuthenticated" class="container-fluid">
<app-app-menu></app-app-menu>
<router-outlet></router-outlet>
</div>
app.component.ts
import { Router } from '@angular/router';
import { Component, OnInit } from '@angular/core';
import { Store } from '@ngrx/store';
import { map } from 'rxjs/operators';
import { AppState } from './app.reducer';
import { UserState } from './core/store/core.state';
import * as CoreActions from './core/store/core.actions';
import { Globals } from './shared/globals';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent implements OnInit {
datetime = new Date();
title = 'curemd-x';
isAuthenticated = false;
constructor(private store: Store<AppState>, private router: Router,
private globals: Globals) {}
...
...
业力错误
"Failed: Template parse errors:
'ngx-spinner' is not a known element:
1. If 'ngx-spinner' is an Angular component, then verify that it is part of this module.
2. If 'ngx-spinner' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' to the '@NgModule.schemas' of this component to suppress this message. ("[ERROR ->]<ngx-spinner bdColor="rgba(51,51,51,0.8)" size="medium" color="#fff" type="ball-scale-multiple">
<p"): ng:///DynamicTestModule/AppComponent.html@0:0
'app-app-menu' is not a known element:
1. If 'app-app-menu' is an Angular component, then verify that it is part of this module.
2. If 'app-app-menu' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' to the '@NgModule.schemas' of this component to suppress this message. ("
</ngx-spinner>
<div *ngIf="isAuthenticated" class="container-fluid">
[ERROR ->]<app-app-menu></app-app-menu>
<router-outlet></router-outlet>
</div>
"): ng:///DynamicTestModule/AppComponent.html@4:2
我也尝试包含 "CUSTOM_ELEMENTS_SCHEMA" 但没有成功。
"app-app-menu" 是核心模块中存在的组件,核心模块在 app.module
中导入app.module.ts
declarations: [
AppComponent,
FirstOrDefaultPipe
],
imports: [
RouterModule,
BrowserModule,
HttpClientModule,
PatientModule,
StoreModule.forRoot(AppReducers),
EffectsModule.forRoot([]),
CoreModule,
NgxSpinnerModule,
BrowserAnimationsModule,
DropDownsModule
],
providers: [Globals],
bootstrap: [AppComponent],
schemas: [CUSTOM_ELEMENTS_SCHEMA]
})
export class AppModule { }
如何才能运行 应用模块实例的成功测试用例?
Angular 开发人员经常对此感到困惑。当您 运行 ng test
、karma 和 jasmine 运行s angular 模块定义在 .spec.ts
文件中时。它根本不查看您的正常代码。所以无论你输入 app.module.ts
对你的测试模块没有任何影响。您可以做两件事。
将
CUSTOM_ELEMENTS_SCHEMA
添加到测试模块在
app.component.spec.ts
内执行以下操作
TestBed.configureTestingModule({
declarations: [
AppComponent
],
schemas: [CUSTOM_ELEMENTS_SCHEMA]
}).compileComponents();
这将解决您现在遇到的错误。但是,您可能会遇到其他人,因为我看到您向 AppComponent
注入了一些服务,这让我们接下来可以做一些事情
在测试模块中导入
AppModule
。您可以按如下方式在
TestBed
中导入AppModule
。这样做的目的是确保您的测试始终具有它们需要定义的内容。如果您将另一个组件添加到AppModule
并在AppComponent
中使用它,它也将在测试中可用。此外,您不需要添加CUSTOM_ELEMENTS_SCHEMA
。但是,您应该知道,这将导入并创建您在
app.component
中使用的任何第 3 方 component/services。有人会争辩说这有悖于单元测试的本质。您仍然可以以某种方式模拟这些服务,但它们将被渲染。此外,在 angular 应用程序中,当测试导入RouterModule
的模块时,将使用RouterTestingModule
代替。在测试中使用RouterModule
可能会搞乱你的测试,因为这些测试 运行 在无头浏览器上和RouterModule
可能会导致 URL 更改。
TestBed.configureTestingModule({
imports: [
AppModule
],
}).compileComponents();
虽然
- 使用
CUSTOM_ELEMENTS_SCHEMA
或NO_ERRORS_SCHEMA
可能会导致“误吞”。如 official doc 中所述,请勿过度使用它们。 - importing
AppModule
意味着您正在编写集成测试。通常,最好编写一个独立的单元测试。
因此,恕我直言,最好的解决方案是存根不需要的组件,如 official doc 中所述。基本上,您将使用相同的选择器创建一个空组件。如果你有很多组件,这可能会很乏味,但我相信这是目前的最佳做法。