我正在使用Spectator编写Angular 8测试,并使用Jest运行它们。根据{{3}},我可以使用setInput()
将我的值分配给有效的字段名称。问题在于创建组件后将对输入进行验证,但是在此之前我需要它,因为我在ngOnInit
方法中将其用于初始化:
// item.component.ts
@Input() items: Items[] = [];
ngOnInit(): void {
// do something with this.items
// read query param 'page' and use it for something
}
与
// item.component.spec.ts
let spectator: SpectatorRouting<ItemComponent>;
const createComponent = createRoutingFactory({
component: ItemComponent,
queryParams: {page: 1}
});
beforeEach(() => spectator = createComponent());
it('test items', () => {
spectator.setRouteQueryParam('page', '2');
spectator.setInput("items", myItemsList);
});
旁观者将正确设置queryParam page
和Input items
,但前提是已经创建了组件。在创建组件期间,ngOnInit
将使用page == 1
和items == []
进行初始化。
我可以在每种方法中创建观众组件,并分别传递queryParams,但是我找不到在createRoutingFactory
参数中传递输入的方法。
或者,我可以使用the README传递我的输入参数,但是我失去了传递我相信的查询参数的能力。
答案 0 :(得分:2)
您可以在createRoutingFactory选项中设置detectChanges = false。这将使createComponent()不会自动调用onInit(),并且在测试中,应在设置输入(或存根/模拟服务间谍)之后调用spectator.detectChanges():
// item.component.spec.ts
let spectator: SpectatorRouting<ItemComponent>;
const createComponent = createRoutingFactory({
component: ItemComponent,
queryParams: {page: 1},
detectChanges: false // set this to avoid calling onInit() automatically
});
beforeEach(() => spectator = createComponent());
it('test items', () => {
spectator.setRouteQueryParam('page', '2');
// spectator.inject(AnyService).doSomething.andReturn()... // stub services if needed
spectator.setInput("items", myItemsList);
spectator.detectChanges(); // Now onInit() will be called
});
答案 1 :(得分:0)
我找到了这个问题的答案。事实证明,这非常简单,设置了模拟和其他参数后,可以再次调用ngOnInit
以重新初始化组件。所以我的测试方法变为:
// item.component.spec.ts
let spectator: SpectatorRouting<ItemComponent>;
const createComponent = createRoutingFactory({
component: ItemComponent,
queryParams: {page: 1}
});
beforeEach(() => spectator = createComponent());
it('test items', () => {
spectator.setRouteQueryParam('page', '2');
spectator.setInput("items", myItemsList);
spectator.component.ngOnInit(); // Now the component is reinitialized and the input will contain myItemsList
});