我有一个想要测试的简单组件。我从另一个组件加载这个组件作为模态:
const modal = this.modalService.create({
nzContent: MyModalComponent
});
组件
@Component({
selector: 'my-modal-component',
template: `
<div *nzModalFooter>
<button nz-button nzType="default" (click)="destroyModal()">
Cancel
</button>
</div>
`
})
export class MyModalComponent{
constructor(private modal: NzModalRef) {}
destroyModal(): void {
this.modal.destroy({});
}
}
为
MyModalComponent
组件创建测试台时,出现错误:
NullInjectorError: StaticInjectorError(DynamicTestModule)[NzModalFooterDirective -> NzModalRef]:
StaticInjectorError(Platform: core)[NzModalFooterDirective -> NzModalRef]:
NullInjectorError: No provider for NzModalRef!
阅读错误后我尝试使用
NzModalFooterDirective
。
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [OtherModules],
declarations: [MyModalComponent],
providers: [
NzModalFooterDirective
]
}).compileComponents();
}));
以及任何其他进口:
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [OtherModules],
declarations: [MyModalComponent],
providers: [
{ provide: NZ_MODAL_CONFIG, useValue: {} },
NzModalService,
NzModalFooterDirective
]
}).compileComponents();
}));
没有成功...
我也尝试过直接使用NzModalRef
describe('MyModalComponent', () => {
let component: MyModalComponent;
let fixture: ComponentFixture<MyModalComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [OtherModules],
declarations: [MyModalComponent],
providers: [NzModalRef]
}).compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(MyModalComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
但随后我收到错误:
this.nzModalRef.getInstance is not a function
我只是想准备测试床。我不确定我导入的
NzModalRef
是否错误,或者是否必须用自定义模拟替换它。
如果你想绕过这个错误,你可以简单地通过
NzModelRef
来模拟
useValue
providers: [
{
provide: NzModalRef,
useValue: {
getInstance: () => {
return {
setFooterWithTemplate: () => {}
};
}
}
}
]
就你而言
describe('MyModalComponent', () => {
let component: MyModalComponent;
let fixture: ComponentFixture<MyModalComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [OtherModules],
declarations: [MyModalComponent],
providers: [{
provide: NzModalRef,
useValue: {
getInstance: () => {
return {
setFooterWithTemplate: () => {}
};
}
}
}]
}).compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(MyModalComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
NzModalRef
是动态注入到NzModalComponent
中的,不需要向providers
声明。
我所做的是设置一个提供者
NzModalRef
用工厂创建一个新的模式:
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [
OtherModules
],
declarations: [MyModalComponent],
providers: [
{
provide: NzModalRef,
useFactory: (modalSvc: NzModalService) => modalSvc.create({
nzClosable: false,
nzContent: MyModalComponent
}),
deps: [NzModalService]
}
]
}).overrideModule(BrowserTestingModule, {
set: {entryComponents: [MyModalComponent]}
}).compileComponents();
}));
还需要在入口组件中添加模态组件。
对于那些想知道如何测试 nzModal 中显示的组件并正确渲染模态标题和页脚的人,我建议您检查 ngZorro 团队自己使用的设置:
他们是这样做的:
他们为一些与测试中的组件完全无关的虚拟组件创建了一个固定装置(在他们的特定用例中,他们使用虚拟组件来检索一些数据以进行检查)
他们通过 INJECTED INTO TEST 服务打开正在测试的组件。这将正确呈现完整的模式,包括标题和页脚
通过此设置,fixture.detectChanges() 还将触发模态内部组件的更改检测(尽管我不知道为什么会发生)