如何对作为viewchild的功能进行单元测试

时间:2019-07-18 06:30:42

标签: angular typescript unit-testing jasmine karma-jasmine

我有一个需要测试作为@Viewchild引用的函数的场景。

我的component.ts

    @ViewChild('accTitle', { read: ViewContainerRef, static: false }) title: ViewContainerRef;
    @ViewChild('accText', { read: ViewContainerRef, static: false }) body: ViewContainerRef;

    constructor(
        private renderEngineService: RenderEngineService,
        @Inject(CONTENT_MAPPINGS) private contentMappings: any,
        private changeDetectorRef: ChangeDetectorRef
    ) {}

    ngAfterViewInit() {
        this.renderEntityRanges(this.item);
    }

    renderEntityRanges(item: AreasData) {
        this.item.sections.forEach(section => {
            if (section.type === 'title') {
                this.renderEngineService.setRootViewContainerRef(this.title);
            } else if (section.type === 'text') {
                this.renderEngineService.setRootViewContainerRef(this.body);
            }
            section.rjf.forEach(rjf => {
                const type = this.contentMappings[rjf.type];
                this.renderEngineService.createComponent(rjf, type);
                this.changeDetectorRef.detectChanges();
            });
        });
    }

所以在我的Spec文件中,我做了以下

  it('should invoke renderEntityRanges', () => {
    const renderEntityRanges = spyOn(accordionItemComponent, 'renderEntityRanges');
    accordionItemComponent.ngAfterViewInit();
    expect(renderEntityRanges).toHaveBeenCalledWith(ACCORDION_ITEM);
  });

上面的测试用例工作正常。

但是我现在确定如何测试此功能renderEntityRanges

剂量为renderEntityRanges,如果ACCORDION_ITEMtype,它将检查title中的类型,然后使用进行服务呼叫this.renderEngineService.setRootViewContainerRef输入为this.title

因此,请帮助如何对该功能进行单元测试。

1 个答案:

答案 0 :(得分:1)

要更正renderEntityRanges,我将this.item删除为item,因为它是作为参数传递的。

    renderEntityRanges(item: AreasData) {
        item.sections.forEach(section => {
            if (section.type === 'title') {
                this.renderEngineService.setRootViewContainerRef(this.title);
            } else if (section.type === 'text') {
                this.renderEngineService.setRootViewContainerRef(this.body);
            }
            section.rjf.forEach(rjf => {
                const type = this.contentMappings[rjf.type];
                this.renderEngineService.createComponent(rjf, type);
                this.changeDetectorRef.detectChanges();
            });
        });
    }

并在构造器中将renderEngineServicechangeDetectorRef设为public进行监视:

public renderEngineService: RenderEngineService,
public changeDetectorRef: ChangeDetectorRef

您可以尝试将其测试为:

it('should set Container Ref and create component',()=>{
   spyOn(accordionItemComponent.renderEngineService,'setRootViewContainerRef').and.callThrough();
   spyOn(accordionItemComponent.renderEngineService,'createComponent').and.callThrough();
   spyOn(accordionItemComponent.changeDetectorRef,'detectChanges').and.callThrough();
   accordionItemComponent.renderEntityRanges(ACCORDION_ITEM);
   expect(accordionItemComponent.renderEngineService.setRootViewContainerRef).toHaveBeenCalled();
   expect(accordionItemComponent.renderEngineService.createComponent).toHaveBeenCalled();
   expect(accordionItemComponent.changeDetectorRef.detectChanges).toHaveBeenCalled();
})

并确保ACCORDION_ITEM的数据同时满足typessection.rjf = [ some array to iterate over]