I'm currently implementing 'unit testing' in my angular application. However, if I run them, I receive multiple warnings/errors similar to this one: 'Error retrieving icon: Unable to find icon with the name ":myIcon"'
. I suspect it might be caused by not adding the svgs to my MatIconRegistry. I usually do this in my AppComponent, like so:
constuctor(private iconRegistry: MatIconRegistry,
private sanitizer: DomSanitizer,
...) {
iconRegistry.addSvgIcon('myIcon', sanitizer.bypassSecurityTrustResourceUrl('./assets/icons/myIcon.svg'));
}
If I run a unit test of another component though, this will not execute and thus not add my svg to the registry. I already tried adding it in my .spec file of the corresponding component, like so:
fdescribe('MyComponent', () => {
let component: MyComponent;
let fixture: ComponentFixture<MyComponent>;
let iconRegistry;
let sanitizer;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [
...
],
imports: [
...
],
providers: [
...
],
schemas: [CUSTOM_ELEMENTS_SCHEMA]
})
.compileComponents();
}));
beforeEach(() => {
iconRegistry = TestBed.get(MatIconRegistry);
sanitizer = TestBed.get(DomSanitizer);
iconRegistry.addSvgIcon('myIcon', sanitizer.bypassSecurityTrustResourceUrl('./../../assets/icons/myIcon.svg'));
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create component', () => {
expect(component).toBeTruthy();
});
});
If I run this, it doesn't work. It just returns a different error message:
Error retrieving icon: <svg> tag not found
My initial thought was that I have made a mistake in the path, but after trying various other paths I'm sure thats not the case.
Does anyone know how do solve this problem? Or maybe there is a better way doing this, since I would have to add my svg icon in every component I'm testing, which would be kinda redundant.
can just do:
This will generate a test icon rendering without the http request
Just spent a couple hours on this. It looks like Angular now provides a
FakeMatIconRegistry
. It squashed about 90% of the karma warnings, but still a few remain...Had to do a lot of this:
There's also another way how to avoid this problem. Spectator (which is btw really awesome tool for Angular unit testing) has handy shallow flag, which basically prevents all child components (including mat-icon) to be compiled but handled as simple HTML tag instead.
With this flag enabled, you don't need to import MatIconModule anymore, also you reduce the test runtime, because Angular doesn't compile extra components while running the test. This allows you to really focus on the component itself while writing unit tests, without worrying about the stuff you don't need anyway.
It's a win-win if you ask me :)
Mock the
mat-icon
selector with the following component at the top of the unit testThen override the MatIconModule in the unit test as follows
You will no longer have the
'Error retrieving icon: Unable to find icon with the name ":myIcon"'
issue when running the unit testsUsing typemoq for mocking; following worked for me:
and then
What you could do is install ng-mocks and use MockModule to mock the MatIconModule in your tests e.g.: