如何测试动态加载组件的 Angular (v11) 组件
在我的代码中,我遵循 Angular v11 指南,
@Directive({
selector: '[stepHostContent]',
})
export class StepHostContentDirective {
constructor(public viewContainerRef: ViewContainerRef) { }
}
@Component({
selector: 'app-dialog-wizard',
templateUrl: './dialog-wizard.component.html',
styleUrls: ['./dialog-wizard.component.scss']
})
export class DialogWizardComponent implements OnInit, OnDestroy {
@ViewChild(StepHostContentDirective, { static: true }) stepHostContent: StepHostContentDirective;
constructor(
public readonly dialog: MatDialogRef<DialogJobsWizardComponent>,
@Inject(MAT_DIALOG_DATA) public readonly data: { theme: string, title: string },
public readonly componentFactoryResolver: ComponentFactoryResolver
) { }
...
private loadStepContentComponent(componentToLoad: Type<any>): void {
const componentFactory = this.componentFactoryResolver.resolveComponentFactory(componentToLoad);
const viewContainerRef = this.stepHostContent.viewContainerRef;
viewContainerRef.clear();
viewContainerRef.createComponent(componentFactory);
}
我的单元测试
describe('DialogWizardComponent', () => {
let component: DialogWizardComponent;
let fixture: ComponentFixture<DialogWizardComponent>;
let componentFactoryResolverSpy = jasmine.createSpyObj<ComponentFactoryResolver>('ComponentFactoryResolver', ['resolveComponentFactory'])
beforeEach(async () => {
componentFactoryResolverSpy = spyComponentFactoryResolverSpy();
await TestBed.configureTestingModule({
declarations: [
DialogsWizardComponent,
MockComponent(DialogBaseComponent),
MockComponent(StepTestAComponent),
MockComponent(StepTestBComponent),
StepHostContentDirective
],
providers: [
{ provide: MatDialogRef, useValue: { close: () => {} } },
{ provide: MAT_DIALOG_DATA, useValue: { theme: 'dark', title: 'Title' } },
{ provide: ComponentFactoryResolver, useValue: componentFactoryResolverSpy },
],
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(DialogWizardComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
错误显示
无法读取未定义的属性(读取'ngModule')
指向这一行viewContainerRef.createComponent(componentFactory);
In my code I'm following Angular v11 guide for that
@Directive({
selector: '[stepHostContent]',
})
export class StepHostContentDirective {
constructor(public viewContainerRef: ViewContainerRef) { }
}
@Component({
selector: 'app-dialog-wizard',
templateUrl: './dialog-wizard.component.html',
styleUrls: ['./dialog-wizard.component.scss']
})
export class DialogWizardComponent implements OnInit, OnDestroy {
@ViewChild(StepHostContentDirective, { static: true }) stepHostContent: StepHostContentDirective;
constructor(
public readonly dialog: MatDialogRef<DialogJobsWizardComponent>,
@Inject(MAT_DIALOG_DATA) public readonly data: { theme: string, title: string },
public readonly componentFactoryResolver: ComponentFactoryResolver
) { }
...
private loadStepContentComponent(componentToLoad: Type<any>): void {
const componentFactory = this.componentFactoryResolver.resolveComponentFactory(componentToLoad);
const viewContainerRef = this.stepHostContent.viewContainerRef;
viewContainerRef.clear();
viewContainerRef.createComponent(componentFactory);
}
My unit test
describe('DialogWizardComponent', () => {
let component: DialogWizardComponent;
let fixture: ComponentFixture<DialogWizardComponent>;
let componentFactoryResolverSpy = jasmine.createSpyObj<ComponentFactoryResolver>('ComponentFactoryResolver', ['resolveComponentFactory'])
beforeEach(async () => {
componentFactoryResolverSpy = spyComponentFactoryResolverSpy();
await TestBed.configureTestingModule({
declarations: [
DialogsWizardComponent,
MockComponent(DialogBaseComponent),
MockComponent(StepTestAComponent),
MockComponent(StepTestBComponent),
StepHostContentDirective
],
providers: [
{ provide: MatDialogRef, useValue: { close: () => {} } },
{ provide: MAT_DIALOG_DATA, useValue: { theme: 'dark', title: 'Title' } },
{ provide: ComponentFactoryResolver, useValue: componentFactoryResolverSpy },
],
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(DialogWizardComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
the error says
Cannot read properties of undefined (reading 'ngModule')
pointing to this line viewContainerRef.createComponent(componentFactory);
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您需要模拟 ViewContainerRef。
You need to mock ViewContainerRef.
https://angular.io/guide/testing-components-basics
我修复了它,从提供程序中删除了 ComponentFactoryResolver,并且它起作用了
I fixed it removing the ComponentFactoryResolver from providers, and it worked