Spectator Angular тестирование - пройти ввод до ngOnInit
Я использую Spectator для написания моих тестов Angular 8 и Jest для их запуска. Согласно README я могу использовать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
и ввод items
правильно, но только после того, как компонент уже создан. При создании компонентаngOnInit
инициализируется page == 1
а также items == []
.
Я мог бы создать компонент-наблюдатель в каждом методе и передать queryParams отдельно, но я не могу найти способ передать ввод в createRoutingFactory
аргументы.
В качестве альтернативы я мог бы использовать фабрику компонентов хоста для передачи моих входных параметров, но тогда я теряю возможность передавать параметры запроса, как я считаю.
1 ответ
Я нашел ответ на этот вопрос. Оказалось довольно просто,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
});
Вы можете установить detectChanges=false в параметрах createRoutingFactory. Это заставит 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
});