【问题标题】:Element not known error in Karma when ran "ng test"运行“ng test”时,Karma 中的元素未知错误
【发布时间】:2019-05-03 09:02:04
【问题描述】:

我的项目在我运行时运行良好

服务

但是当我使用运行一个简单的“tobeTruthy()”测试用例时它显示了多个错误

ng 测试

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 { }

如何为应用模块实例运行成功的测试用例?

【问题讨论】:

  • 您可以尝试运行npm run prod-build-staging --verbose。也许这会给你更多的细节

标签: angular unit-testing karma-runner


【解决方案1】:

Angular 开发人员经常对此感到困惑。当您运行ng test 时,karma 和 jasmine 会运行在.spec.ts 文件中定义的角度模块。它根本不查看您的正常代码。因此,无论您在 app.module.ts 中输入什么内容,都不会对您的测试模块产生任何影响。您可以做两件事。

  1. CUSTOM_ELEMENTS_SCHEMA添加到测试模块

    app.component.spec.ts 内执行以下操作

   TestBed.configureTestingModule({
      declarations: [
        AppComponent
      ],
      schemas: [CUSTOM_ELEMENTS_SCHEMA]
   }).compileComponents();

这将解决您现在遇到的错误。但是,您可能会遇到其他人,因为我已经看到您向 AppComponent 注入了一些服务,这使我们接下来可以做的事情

  1. 在测试模块中导入AppModule

    您可以在TestBed 中导入AppModule,如下所示。这将确保您的测试始终具有他们需要定义的内容。如果您向AppModule 添加另一个组件并在AppComponent 中使用它,它也将在测试中可用。此外,您无需添加CUSTOM_ELEMENTS_SCHEMA

    但是,您应该知道,这将导入和创建您在 app.component 中使用的任何第 3 方组件/服务。有人会争辩说,这违反了单元测试的本质。您仍然可以以某种方式模拟这些服务,但它们会被渲染。此外,在 Angular 应用程序中,当测试导入 RouterModule 的模块时,将使用 RouterTestingModule 代替。在测试中使用 RouterModule 可能会弄乱您的测试,因为这些测试在无头浏览器上运行,RouterModule 可能会导致 URL 更改。

    TestBed.configureTestingModule({
      imports: [
        AppModule
      ],
    }).compileComponents();

【讨论】:

  • 太棒了!但是如果我不想导入整个 appModule 并且我必须导入、声明并提供多个包或服务以使其工作,我可以简单地将它添加到我的 spec.ts 文件中,就像我将添加到 module.ts 中一样?
  • 另外,如果我在 spec.ts 中添加一些不在 module.ts 中的额外内容,它们会在我运行“ng serve”时影响我的项目大小或编译时间吗?我认为当我运行“ng test”时它会明显产生影响
  • 无论您在spec 文件中做什么,都不会影响您的应用。此外,是的,您可以在 spec 文件中导入任何您想要的内容。如果您不想自己导入AppModule,我建议您模拟服务和组件,而不是导入实际的模块。
【解决方案2】:

虽然accepted answer 是正确的,意味着它有效地解决了问题,但请注意以下几点:

  • 使用CUSTOM_ELEMENTS_SCHEMANO_ERRORS_SCHEMA 可能会导致“吞咽错误”。如official doc 中所述,请勿过度使用它们。
  • 导入AppModule 表示您正在编写集成测试。通常,最好编写一个独立的单元测试

因此恕我直言,最好的解决方案是存根不需要的组件,如official doc 中所述。基本上,您将使用相同的选择器创建一个空组件。如果您有很多组件,这可能会很乏味,但我相信这是目前的最佳做法。

【讨论】:

    猜你喜欢
    • 2017-06-13
    • 2017-11-14
    • 2019-10-03
    • 1970-01-01
    • 1970-01-01
    • 2011-04-16
    • 2017-04-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多