I have made a component in which I am dynamically loading another component which is working fine on ng serve
. Below is the code for dynamically loading the component.
import { Component, OnInit, ViewChild, ComponentFactoryResolver, Type, Input} from '@angular/core';
import { AddComponentDirective } from '../add-component.directive';
import { DynamicComponent } from '../dynamic/dynamic.component';
import { ComponentData } from '../component-data';
import { ComponentItem } from '../component-item';
export class DynamicLoaderComponent implements OnInit {
@ViewChild (AddComponentDirective) adhost : AddComponentDirective;
constructor(private componentFactoryResolver : ComponentFactoryResolver) { }
ngOnInit() {
this.loadComponent(DynamicComponent,message,this.adhost);
}
loadComponent(comp, message, host){
let adItem = new ComponentItem(comp,{msg: message});
let componentFactory = this.componentFactoryResolver.resolveComponentFactory(adItem.component);
let viewContainerRef = host.viewContainer;
let componentRef = viewContainerRef.createComponent(componentFactory);
(<ComponentData>componentRef.instance).data = adItem.data;
}
}
But while testing it with angular karma test, we are facing type error i.e.
TypeError: this.componentFactoryResolver.resolveComponentFactory is not a function
Below is the spec.ts file how I am testing it.
import { async, ComponentFixture, TestBed ,getTestBed,inject} from '@angular/core/testing';
import {ComponentFactoryResolver,ViewChild,DebugElement} from '@angular/core';
import { AddComponentDirective } from '../add-component.directive';
import { DynamicComponent } from '../dynamic/dynamic.component';
import { DynamicLoaderComponent } from './dynamic-loader.component';
import { BrowserDynamicTestingModule } from "@angular/platform-browser-dynamic/testing";
import { ComponentData } from "../component-data";
describe('DynamicLoaderComponent', () => {
let component: DynamicLoaderComponent;
let fixture: ComponentFixture<DynamicLoaderComponent>;
let injector: TestBed;
let componentFactoryResolver : ComponentFactoryResolver ;
let debugElement: DebugElement
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ DynamicLoaderComponent,AddComponentDirective ,DynamicComponent],
providers:[DynamicLoaderComponent,ComponentFactoryResolver]
})
.compileComponents();
TestBed.overrideModule(BrowserDynamicTestingModule, {
set: {
entryComponents: [DynamicComponent]
}
});
}));
beforeEach(() => {
fixture = TestBed.createComponent(DynamicLoaderComponent);
component = fixture.componentInstance;
componentFactoryResolver = fixture.debugElement.injector.get(ComponentFactoryResolver);
fixture.detectChanges();
});
it('should create the DynamicLoaderComponent',inject([DynamicLoaderComponent], (component : DynamicLoaderComponent) => {
expect(component).toBeTruthy();
}));
});
Can you help me solve this issue so that I can proceed further in the testing of dynamic components?
There are several changes you need to make to fix those errors:
1) Remove providers
from TestBed configuration
TestBed.configureTestingModule({
declarations: [ DynamicLoaderComponent,AddComponentDirective ,DynamicComponent],
providers:[DynamicLoaderComponent,ComponentFactoryResolver] <== remove this line
})
2) You do not need to get your component from DI,
so replace
it('should create the DynamicLoaderComponent', inject([DynamicLoaderComponent], (component : DynamicLoaderComponent) => {
expect(component).toBeTruthy();
}));
with:
it('should create the DynamicLoaderComponent', () => {
expect(component).toBeTruthy();
});
3) compileComponents()
call is only needed if you run tests in a non-CLI environment.
From Angular doc
Calling compileComponents() closes the current TestBed instance to further configuration. You cannot call any more TestBed configuration methods, not configureTestingModule() nor any of the override... methods. The TestBed throws an error if you try.
That means that your TestBed.overrideModule
call won't have any effect and DynamicComponent
's factory won't be found.
So remove .compileComponents();
TestBed.configureTestingModule({
declarations: [ DynamicLoaderComponent,AddComponentDirective ,DynamicComponent],
providers:[DynamicLoaderComponent,ComponentFactoryResolver]
})
.compileComponents(); <==== remove this
If you're on non-angular-cli environment then you can call it after overriding module:
TestBed.overrideModule(BrowserDynamicTestingModule, {
set: {
entryComponents: [DynamicComponent]
}
});
TestBed.compileComponents(); <== this line
After all changes I've written above, the test should be executed without any errors.
Plunker Example
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With