Angular 2.0.0-rc.1:如何测试视图或内容上的元素(例如@ViewChildren、@ContentChildren)
Angular 2.0.0-rc.1: How to test elements on the view or content (e.g. @ViewChildren, @ContentChildren)
我有一个组件从在 View
上创建 children 的服务获取数据。那些 children 仅在创建 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
初始化后创建的内容?
我会利用 async
函数:
it('should initialise children', async(inject([ComponentToTest], (component: ComponentToTest, service: Service) => {
return service.getData().toPromise().then(() => {
expect(component.children).toBeDefined();
});
})));
来自文档:
Wraps a test function in an asynchronous test zone. The test will automatically complete when all asynchronous calls within this zone are done. Can be used to wrap an inject call
注入组件只会创建组件的实例class,但不会调用生命周期回调,也不会创建视图。
您需要改用 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()
。
我有一个组件从在 View
上创建 children 的服务获取数据。那些 children 仅在创建 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
初始化后创建的内容?
我会利用 async
函数:
it('should initialise children', async(inject([ComponentToTest], (component: ComponentToTest, service: Service) => {
return service.getData().toPromise().then(() => {
expect(component.children).toBeDefined();
});
})));
来自文档:
Wraps a test function in an asynchronous test zone. The test will automatically complete when all asynchronous calls within this zone are done. Can be used to wrap an inject call
注入组件只会创建组件的实例class,但不会调用生命周期回调,也不会创建视图。
您需要改用 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()
。