Как обнаружить отсутствующий тик () в fakeAsync () - PullRequest
0 голосов
/ 10 сентября 2018

Я написал этот тест для моего приложения 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. Обратите внимание, что вам нужно нажать кнопку «обновить» в представлении внутреннего браузера (рядом с редактором), если вы хотите перезапустить тест или после того, как вы что-то изменили. Функция автоматической перезагрузки не будет работать и выдает ошибки.

Я отправил вопрос , как кто-то предложил в комментариях.

1 Ответ

0 голосов
/ 12 сентября 2018

Эта проблема показывает, что в настоящее время fakeAsync() не создает исключение для ожидающих микро-задач, а только для ожидающих таймеров. На данный момент, кажется, нет никакого способа гарантировать, что в конце теста нет ожидающих выполнения микро-задач. Тем не менее, разработчики собираются проверить, если это особенность.

...