12

我正在尝试对使用 angular-material2 的组件编写测试,但是当我将其添加到我的 testModule 声明中时,我得到:

Error: Template parse errors:
    'md-card-title' is not a known element:
    1. If 'md-card-title' is an Angular component, then verify that it is part of this module.
    2. If 'md-card-title' is a Web Component then add "CUSTOM_ELEMENTS_SCHEMA" to the '@NgModule.schemas' of this component to suppress this message.

将 MaterialModule 添加到声明中会引发“错误:模块声明的意外模块“MaterialModule”

config/spec-bundle.js 中的 DynamicTestModule'(第 24994 行)

这是我的规范文件的样子:

  beforeEach(() => TestBed.configureTestingModule({
    declarations: [],
    providers: [
      { provide: DataService, useValue: mockDataService },
      { provide: ActivatedRoute, useClass: MockActivatedRoute },
      { provide: Router, useValue: mockRouter },
      CellViewComponent
    ]
  }));

添加CellViewComponent到声明数组会导致错误抛出。

4

3 回答 3

24

当您使用 时TestBed.configureTestingModule,您将从头开始为测试环境创建一个模块。因此,您在实际应用程序中需要什么CellViewComponent才能工作,您还需要在测试模块中对其进行配置。

在您的情况下,您缺少材料卡组件。在应用程序中,您可能将MaterialModule或导入MdCardModule到您的AppModule. 所以你需要在测试模块中做同样的事情

beforeEach(() => TestBed.configureTestingModule({
  imports: [ MaterialModule /* or MdCardModule */ ],
  declarations: [  CellViewComponent ],
  providers: [
    { provide: DataService, useValue: mockDataService },
    { provide: ActivatedRoute, useClass: MockActivatedRoute },
    { provide: Router, useValue: mockRouter },
  ]
}));
于 2016-10-26T17:55:13.153 回答
9

这是一个真正的问题:除了导入组件的选择器之外,您可以模拟所有内容。

有一个简单的方法。它允许避免导入模块,而是您可以禁用此类错误。

只需将其添加到您的模块中:

import { NO_ERRORS_SCHEMA } from '@angular/core';

...

TestBed.configureTestingModule({
  schemas: [ NO_ERRORS_SCHEMA ],
  ...

Angular2 文档链接

是的,如果您想进行集成(不是隔离)测试,这将无济于事,但它非常适用于隔离测试。

尽管如此,即使您决定导入一个模块,我认为导入带有所有已实现选择器的模拟模块可能更正确。

于 2016-11-08T11:19:13.897 回答
0

在测试我们的 Angular 应用程序组件时,我经常做的就是通过引用导入父模块。对于大多数用例来说,这已经足够或接近足够了,如果您通过添加新的声明或导入来更改组件,那么您无需担心更改测试文件,因为测试文件会导入父模块。

我只更改模块以导入一些外部组件以进行测试,但这很少见。

正则测试初始化​​伪代码

beforeEach(() => TestBed.configureTestingModule({
    declarations: [
        ComponentA,
        ComponentB
    ],
    providers: [
        CellViewComponent
    ]
}));

假设这个组件在一个模块中。我将声明对象放入一个变量中,以便同时在 ParentModule 和 Testing 中使用。

export var ParentModuleArgs = {
    declarations: [
        ComponentA,
        ComponentB
    ],
    providers: [
        CellViewComponent
    ]
  };

@NgModule(parentModuleArgs)
export class ParentModule {}

然后,我没有将整个 Module 数组重写到测试组件中并且非常不干燥,而是这样做了。

beforeEach(() => TestBed.configureTestingModule(ParentModuleArgs));

如果我需要添加一些东西,那么我们可以在配置测试台之前添加它

let moduleArgs: NgModule = ParentModuleArgs;
moduleArgs.providers.push({provide: APP_BASE_HREF, useValue: '/'});

beforeEach(() => TestBed.configureTestingModule(ParentModuleArgs));
于 2019-06-19T13:58:44.003 回答