Я написал этот тест для моего приложения Angular:
it('should request confirmation before deleting & abort action if user declined', fakeAsync(() => {
spyOn(appService, 'confirm').and.returnValue(of(false));
spyOn(personService, 'delete').and.callThrough();
component.deleteEntry(testPerson);
//tick(); // Missing tick()!
expect(personService.delete).not.toHaveBeenCalled();
}));
Это метод компонента, который я тестирую:
async deleteEntry(person: Person) {
if (await this.appService.confirm().toPromise()) {
return;
}
try {
await this.personService.delete(person).toPromise();
} catch(resp) {
this.appService.errorMsgBox();
}
}
(цель confirm()
- показать диалоговое окно подтверждения и вернуть наблюдаемое излучение true
/ false
в зависимости от ввода пользователя)
Если вы внимательно посмотрите, в моей компонентной функции есть ошибка. Я забыл !
-оператор при проверке результата confirm()
. Правильный код будет
if (!await this.appService.confirm().toPromise()) {
Однако тест пройден. Я не уверен на 100%, но я предполагаю, что это проходит, потому что expect()
-состояние в конце выполняет проверку до того, как confirm()
вернет свое значение. Так что да, конечно, personService.delete()
не был назван. Если я раскомментирую tick()
, тест будет работать, как ожидается, и обнаружит ошибку.
Теперь я ожидал, что fakeAsync()
выдаст ошибку из-за ожидающих выполнения микрозадач. К моему удивлению, это не так. Тест проходит без каких-либо ошибок или предупреждений, хотя в документах написано :
Если в конце функции имеются ожидающие таймеры, будет выдано исключение.
Так что, похоже, у нас есть условие гонки, то есть confirm()
разрешается до возврата fakeAsync()
, но после expect()
. Если это возможно, что за дело с fakeAsync()
, если не контролировать эти вещи?
Возможно, я и другие разработчики забудем также tick()
или flushMicrotasks()
в будущем. Вот и мне интересно, как этого избежать. Есть ли какая-то вспомогательная функция, которую мне не хватает, которую я могу вставить в afterEach()
? Или поведение fakeAsync()
является угловой ошибкой, т. Е. Должно выдаваться исключение?
EDIT
Смотрите полный рабочий пример моей проблемы со Stackblitz: https://stackblitz.com/edit/angular-cnmubr. Обратите внимание, что вам нужно нажать кнопку «обновить» в представлении внутреннего браузера (рядом с редактором), если вы хотите перезапустить тест или после того, как вы что-то изменили. Функция автоматической перезагрузки не будет работать и выдает ошибки.
Я отправил вопрос , как кто-то предложил в комментариях.