2

我有一个组件从服务中获取数据,该服务在View. 这些子级仅在View创建时可用。在我下面的示例中,View在它到达测试之前没有创建它,因此测试 2 失败。

零件:

@Component({
  selector: 'component-to-test',
  providers: [Service],
  directives: [NgFor, ChildComponent],
  template: `
    <child [data]="childData" *ngFor="let childData of data"></child>
})

export class ComponentToTest implements OnInit {
  @ViewChildren(ChildComponent) children: QueryList<ChildComponent>;
  private data: any;

  public ngOnInit() {
    this.getData();
  }

  private getData() {
    // async fetch data from a service
  }
}

规格:

describe('ComponentToTest', () => {
  beforeEach(inject([ComponentToTest], (component: ComponentToTest) => {
    component.ngOnInit();
  }));


  it('should initialise data', inject([ComponentToTest], (component: ComponentToTest, service: Service) => {
    return service.getData().toPromise().then(() => {
      expect(component.data).toBeDefined();
    })
  }));

  it('should initialise children', inject([ComponentToTest], (component: ComponentToTest, service: Service) => {
    return service.getData().toPromise().then(() => {
      expect(component.children).toBeDefined();
    })
  }));
});

测试 1 通过,测试 2 失败。你如何测试在初始化之后创建的View东西?Content

4

2 回答 2

2

注入组件只会创建组件类的实例,但不会调用生命周期回调,也不会创建视图。

您需要TestComponentBuilder改用:

describe('ComponentToTest', () => {
  let component: ComponentToTest;
  beforeEach(async(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => {
    tcb.createAsync(ComponentToTest).then((fixture: ComponentFixture<ComponentToTest>) => {
      fixture.detectChanges();
      component = fixture.componentInstance;
      // component.ngOnInit(); // called by `fixture.detectChanges()`
    });
  })));

  it('should initialise children', () => {
    expect(component.children).toBeDefined();
  });
});

为了确保在所有异步执行完成之前测试不会结束,还可以使用async()Thierry 已经提到的方法。

于 2016-06-03T12:48:38.450 回答
0

我会利用这个async功能:

it('should initialise children', async(inject([ComponentToTest], (component: ComponentToTest, service: Service) => {
  return service.getData().toPromise().then(() => {
    expect(component.children).toBeDefined();
  });
})));

从文档中:

在异步测试区域中包装测试函数。当该区域内的所有异步调用都完成时,测试将自动完成。可用于包装注入调用

于 2016-06-03T12:41:39.213 回答