Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Testing components with Font Awesome Icons Module

I'm currently working in an Angular 6 project where I have imported several of the new font-awesome 5 icons using the Fort-awesome module for angular.

As expected, by doing so now some of my Unit Tests (Karma + Jasmine) won't pass due to not being able to render the fa-icon selectors in my pages.

I understand that I could use a CUSTOM_ELEMENTS_SCHEMA in the TestBed for each component but I don't know if by doing so I may have other side effects that would make my unit tests less reliable (i.e. other sub-components may stop being tested).

Another option is to simply import the module in each of the required unit tests, and in each of those, also add the library.add() with the required icons. I do think, however, this could end up being tedious as there may be between 20 and 50 icons depending on the type of application.

I've also thought, but haven't tried yet, to add a stub module for the icons, so I simply "ignore" them. I think this could be reasonable, but not sure what the best practice would be in this case.

Below an excerpt of my imports in 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';

And in the constructor

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

Full repo here: https://github.com/Narshe1412/Code-Institute-Interactive-Frontend-Project/tree/taskman

As I know this is not debate forum I would simply ask:

  • What are the side effects of using CUSTOM_ELEMENTS_SCHEMA in this use case and, if reliability is an issue when using this, which of the other two options would be preferable?
like image 604
Narshe Avatar asked Nov 29 '22 21:11

Narshe


1 Answers

I do not like the other solutions, even if they may work. To me it seems unclean importing the AppModule in a unit test.

My solution is to separate the icons from the other stuff, as described below. This solution is kind of like the already accepted answer, but cleaner in my opinion:

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);
  }
}

Then import the IconsModule wherever you need it, be it in the application itself or in a test:

AppModule:

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

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

Unit Test:

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>

Nice side effect: If you ever were to change the font library from Font Awesome to something else, this is much easier now, as you only have to change the IconsModule and the respective HTML code for the icons.

like image 177
1FpGLLjZSZMx6k Avatar answered Dec 15 '22 05:12

1FpGLLjZSZMx6k