使用字体真棒图标模块测试组件



我目前正在一个 Angular 6 项目中工作,我使用 Fort-awesome 模块导入了几个新的 font-awesome 5 图标。

正如预期的那样,现在这样做我的一些单元测试(Karma + Jasmine)将无法通过,因为无法在我的页面中呈现fa图标选择器。

我知道我可以在 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的副作用是什么,如果在使用它时可靠性是一个问题,那么其他两个选项中的哪一个更可取?

我不喜欢其他解决方案,即使它们可能有效。对我来说,在单元测试中导入AppModule似乎不干净。

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

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

单元测试:

describe('MyComponent', () => {
let component: MyComponent;
let fixture: ComponentFixture<MyComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ MyComponent ],
imports: [
...
IconsModule,
]
})
.compileComponents();
}));
...
});

.HTML:

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

不错的副作用:如果您要将字体库从Font Awesome更改为其他内容,那么现在这要容易得多,因为您只需要更改图标的IconsModule和相应的HTML代码即可。

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

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

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

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

该模块引入了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();

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

看起来这个问题已经有一个公认的答案,但我会尝试补充相关主题的信息。

您可以模拟来自外部模块的所有内容,但可以模拟导入组件的选择器。有一种简单的方法是禁用您提到的此类错误。

无法绑定到"图标",因为它不是"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();

最新更新