Я пытаюсь написать модульный тест, чтобы утверждать, что переменная в компоненте изменилась после отправки формы в многоэтапном сценарии формы. Многошаговая форма является функциональной, но не тестируемой. Я также не уверен, как отладить это, чтобы определить root причину неудачного теста.
Учитывая следующий метод функционального компонента:
submitFileForm(form: NgForm): void {
if (this.uploadFile) {
const reader = new FileReader();
fromEvent(reader, 'error')
.subscribe((e: ProgressEvent) => {
console.error(e);
reader.abort();
});
fromEvent(reader, 'loadend')
.pipe(map(() => btoa(reader.result as string)))
.subscribe(() => {
// This works, but not in the test.
component.step = 1;
}, (err) => {
console.error(err);
this.step = -1;
});
reader.readAsText(this.uploadFile, 'UTF-8');
}
}
И следующий тест:
it('should go from step 0 to step 1', () => {
const mockBlob: any = new Blob([
`A,B,C\naaaa,bbb,ccc`,
], { type: 'text/csv' });
mockBlob.name = 'my.csv';
const mockFile = mockBlob as File;
component.uploadFile = mockFile;
fixture.detectChanges();
component.submitFileForm(component.fileForm);
fixture.detectChanges();
// This fails. component.step is 0. After the test is finished step is 1.
expect(component.step).toEqual(1);
}
Полный пример на https://stackblitz.com/edit/angular-zr3nej и https://angular-zr3nej.stackblitz.io/, который показывает дополнительную информацию. Они находятся в Angular 8.
Я пробовал
- Абстрагирование читателя в свой собственный сервис.
- Упаковка fromEvent с использованием
NgZone.run
и NgZone.runOutsideAngular
. - Обтекание
NgZone.run(() => { component.step = 1; });
- Использование BehaviorSubject для шага формы.
- Отметка ApplicationRef.
- Использование
fixture.whenStable()
в тесте .
Но я думаю, что это, вероятно, связано с фундаментальным неправильным пониманием Angular или Zone и с тем, как правильно зарегистрировать отложенную задачу для компонента Angular. Также мог бы быть лучший способ структурировать код так, чтобы он был тестируемым модулем другим способом. Может быть, вместо ожидания отправки формы читатель всегда может читать? Или, может быть, async / await, но я не очень знаком с этими шаблонами в сочетании с Rx JS и Angular.
Я не пробовал вводить ChangeDetectionRef
, потому что столкнулся с проблемой в прошлое с созданием , что тестируемым.
Шаблон ngSwitch здесь, вероятно, не самый чистый, но, по моему мнению, он все же должен быть возможен. Лично я, вероятно, разбил бы его на отдельные компоненты, но иногда нам нужно придерживаться общих стилей кода.