使用Font Awesome Icons模块测试组件

时间:2019-03-24 21:39:20

标签: angular unit-testing karma-jasmine

我目前在Angular 6项目中工作,我已经使用Fort-awesome模块导入了几个新的字体真棒5图标,以实现角度。

如预期的那样,由于无法在页面中呈现图标选择器,因此现在执行某些单元测试(Karma + Jasmine)不会通过。

我知道我可以在TestBed中为每个组件使用CUSTOM_ELEMENTS_SCHEMA,但是我不知道这样做是否会产生其他副作用,使我的单元测试不太可靠(即其他子组件可能不再测试)。

另一个选择是简单地在每个必需的单元测试中导入模块,并且在每个单元测试中,还添加带有必需图标的library.add()。但是,我确实认为这可能会很乏味,因为取决于应用程序的类型,可能会有20到50个图标。

我也曾考虑过但尚未尝试为图标添加存根模块,因此我只是“忽略”了它们。我认为这可能是合理的,但不确定这种情况下的最佳做法。

下面是我在App.Module中导入的摘录

import { FontAwesomeModule } from '@fortawesome/angular-fontawesome';
import { library } from '@fortawesome/fontawesome-svg-core';
import { faLock, faHourglassHalf, faLockOpen } from '@fortawesome/free-solid-svg-icons';

在构造函数中

export class AppModule {
  constructor() {
    library.add(
      faHourglassHalf, // Task in progress
      faLockOpen, // Archive task
      faLock
    );
  }
} 

此处有完整的回购清单:https://github.com/Narshe1412/Code-Institute-Interactive-Frontend-Project/tree/taskman

据我所知,这不是辩论论坛,我只会问:

  • 在此用例中使用CUSTOM_ELEMENTS_SCHEMA有什么副作用?如果在使用时会带来可靠性问题,那么其他两个选项中的哪一个会更可取?

4 个答案:

答案 0 :(得分:6)

您现在可以像这样使用超棒的测试模块:

import {FontAwesomeTestingModule} from '@fortawesome/angular-fontawesome/testing';

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

答案 1 :(得分:4)

我不喜欢其他解决方案,即使它们可能有效。对我来说,在单元测试中导入import { NgModule } from '@angular/core'; import { FontAwesomeModule, FaIconLibrary } from '@fortawesome/angular-fontawesome'; import { faDownload, faUpload, faFileExport, faCircle, faChevronRight, faChevronDown, faPlus, faTimes } from '@fortawesome/free-solid-svg-icons'; @NgModule({ imports: [ FontAwesomeModule ], exports: [ FontAwesomeModule ] }) export class IconsModule { constructor(library: FaIconLibrary) { // add icons to the library for convenient access in other components library.addIcons(faDownload, faUpload, faFileExport, faCircle, faChevronRight, faChevronDown, faPlus, faTimes); } } 似乎是不干净的。

我的解决方案是将图标与其他内容分开,如下所述。这种解决方案有点像已经接受的答案,但我认为更干净:

import { IconsModule } from './icons.module';

@NgModule({
  declarations: [...],
  imports: [
    ...
    IconsModule,
  ],
  bootstrap: [...]
})
export class AppModule {}

然后将IconModule导入到您需要的位置,无论是在应用程序本身还是在测试中:

AppModule:

describe('MyComponent', () => {
  let component: MyComponent;
  let fixture: ComponentFixture<MyComponent>;

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

  ...

});

单元测试:

<fa-icon icon="download"></fa-icon>

HTML:

IconsModule

很好的副作用:如果您曾经将字体库从Font Awesome更改为其他内容,那么现在这将变得更加容易,因为您只需更改图标的a <-c(0,1) while(length(a)<40){ position <- length(a) new <- a[position] + a[position-1] a<-c(a,new) } print(a) 和相应的HTML代码。

答案 2 :(得分:1)

我只想提出一个“第三”选项。这是我和我的团队一直在使用并喜欢的方法。

该模块引入了FontAwesomeModule。

import { NgModule } from '@angular/core';
import { FontAwesomeModule } from '@fortawesome/angular-fontawesome';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    FontAwesomeModule
  ],
  exports: [
    FontAwesomeModule
  ]
})

export class AppModule { }

实际上使用字体超棒图标的组件仅导入它需要了解的图标。

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

import { faLock } from '@fortawesome/free-solid-svg-icons';

@Component({
  selector: 'app-fa-example',
  template: '<fa-icon [icon]="faLock"></fa-icon>'
})
export class AppComponent {
  faLock = faLock;
}

然后在我们的*.spec.ts文件中,我们进行如下设置:

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

由于FontAwesomeModule是在AppModule中导出的,因此可以通过AppModule导入在此处用于测试平台。由于图标是在组件中显式导入的,因此这里无需library.add(...)指定模块/组件中使用的所有字体真棒图标。

答案 3 :(得分:0)

看起来已经有一个可以解决这个问题的答案,但是我将尝试用相关主题的信息作为补充。

您可以模拟外部模块中的所有内容,但可以模拟导入的组件的选择器。如前所述,有一种简单的方法可以禁用这种错误。

Can't bind to 'icon' since it isn't a known property of 'fa-icon'

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

...

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

NO_ERRORS_SCHEMA告诉Angular编译器忽略无法识别的元素和属性。

否则,我建议将FontAwesome直接添加到测试平台,尽管这是一项繁琐的任务。它提高了可读性,并避免了在测试模块中导入冗余组件。当您拥有多个组件时,这主要成为问题。

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