我有一个组件,它从在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
后创建的内容?
注入组件只会创建组件类的实例,但不会调用生命周期回调,也不会创建视图。
您需要改用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();
});
});
为了确保测试不会在所有异步执行完成之前结束,还要使用 Thierry 已经提到的async()
。
我会利用async
函数:
it('should initialise children', async(inject([ComponentToTest], (component: ComponentToTest, service: Service) => {
return service.getData().toPromise().then(() => {
expect(component.children).toBeDefined();
});
})));
从文档中:
将测试函数包装在异步测试区域中。完成此区域内的所有异步调用后,测试将自动完成。可用于包装注入调用