Angular 5使用材料,jasmine karma测试失败,带有mat-icon

时间:2017-12-21 23:44:43

标签: angular angular-material karma-jasmine angular-material2

我试图用

来运行茉莉花业力
ng test

对Angular Materials的所有问题感到惊讶。几个月前我看到的是OLDER版材料的例子,当它被称为md-icon而不是mat-icon等...

因此,这并不能解决引发的错误

MaterialModule.forRoot()

错误

  

mat-icon不是已知的元素角度材料

4 个答案:

答案 0 :(得分:21)

我遇到了测试材料组件的相同问题。

感谢k.vincent在评论中为我提供了正确答案。

对于使用Material的组件,请确保* .spec文件与此类似:

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

...

beforeEach(async(() => {
    TestBed.configureTestingModule({
        declarations: [ MyComponent ],
        schemas: [ CUSTOM_ELEMENTS_SCHEMA ]
    })
    .compileComponents();
}));

答案 1 :(得分:0)

我的测试也失败了,因为不能绑定到'formGroup',因为它不是'form'的已知属性如果“ app-forgot-password”是Angular组件,则确认它是该模块的一部分如果“ mat-card”是Angular组件,请验证它是否是此模块的一部分。在规范文件中,我添加了ReactiveFormsModule和CUSTOM_ELEMENTS_SCHEMA的导入,并且可以正常工作。

import { ReactiveFormsModule } from '@angular/forms';
import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';

beforeEach(async(() => {
TestBed.configureTestingModule({
  declarations: [ ForgotPasswordComponent ],
  imports: [ReactiveFormsModule],
  schemas: [CUSTOM_ELEMENTS_SCHEMA]
})
.compileComponents();
}));

然后我又遇到一个错误:无法绑定到“ routerLink”,因为它不是“ a”的已知属性。我可以通过在spec文件中添加RouterTestingModule来解决此问题:

import {RouterTestingModule} from '@angular/router/testing';

beforeEach(async(() => {
TestBed.configureTestingModule({
  imports: [
    FormsModule,
    ReactiveFormsModule,
    BrowserAnimationsModule,
    MaterialModule,
    RouterTestingModule
  ],
  declarations: [ LoginFormComponent ]
})
.compileComponents();
}));

答案 2 :(得分:0)

我正在使用Angular 9,并从another answer那里获得了一些线索,最终复制了source file from FakeMatIconModule并像这样使用它:

imports: [
  MatIconModule,
  MatIconTestingModule,
],

它不会呈现图标。

答案 3 :(得分:0)

我正在使用Angular 9,并从another answer那里获得了一些线索,从而找到了一种渲染图标的方法。解决方案是找到应用程序在哪里注册了图标,然后显式调用该注册。 MatIconRegistry需要HttpClientModule的问题。

背景:
app.component.ts中,我正在使用服务IconService,并在其上调用registerIcons方法。

缩写IconService

constructor(
  private matIconRegistry: MatIconRegistry,
  private domSanitizer: DomSanitizer
) { }

public registerIcons(): void {
  ...
  this.matIconRegistry.addSvgIcon(key, this.domSanitizer.bypassSecurityTrustResourceUrl(iconUrl));
});

所以在我的测试中,我:

TestBed.configureTestingModule({
  declarations: [
    ...
  ],
  imports: [
    MatIconModule,
    HttpClientModule,
  ],
  providers: [
    // MatIconRegistry, <- strangely enough not needed.
    {
      provide: DomSanitizer,
      useValue: {
        sanitize: (ctx: any, val: string) => val,
        bypassSecurityTrustResourceUrl: (val: string) => val,
      },
    },
    IconService,
  ]
})
  .compileComponents();

beforeEach(() => {
  TestBed.inject(IconService).registerIcons();
});

iconsEnums.ts:

export enum Icon {
    cloud = 1,
    drop,
    rain,
}

iconService.ts:

@Injectable({
  providedIn: 'root'
})
export class IconService {

  constructor(
    private matIconRegistry: MatIconRegistry,
    private domSanitizer: DomSanitizer
  ) { }

  public registerIcons(): void {
    const iconValues = this.getEnumValues(Icon);
    iconValues.forEach(key => {
      const iconUrl = (`../assets/icons/${key}-icon.svg`);
      this.matIconRegistry.addSvgIcon(key, this.domSanitizer.bypassSecurityTrustResourceUrl(iconUrl));
    });
  }

  private getEnumValues(enumType: any): string[] {
    return Object.values(enumType).filter(v => typeof v === 'string') as string[];
  }
}