Тестирование Angular 7 — асинхронный вызов функции асинхронное ..ожидание

#angular #unit-testing #karma-jasmine #angular7 #angular-test

#angular #модульное тестирование #карма-jasmine #angular7 #angular-тест

Вопрос:

Есть ли способ избежать двойного async( async(){} ) синтаксиса в модульном тестировании Angular 7 при объединении поддержки async с async..await ключевыми словами?

Я новичок в angular, но являюсь опытным программистом, и у меня возникли проблемы с выбором моего предпочтительного стиля тестирования.

Я хотел бы безопасно использовать async..await в тестах, и я понимаю приведенный ниже синтаксис. Однако при обучении разработчиков, не знакомых с современным javascript и / или концепцией async..await двойного async(async()) синтаксиса, это кажется им избыточным и сбивающим с толку. Они не учитывают внешнюю асинхронность. Исключения, возникающие в службе, приводят к тому, что сообщения о сбоях появляются вне фактического теста, что трудно отследить.

Кажется, что одно из следующих было бы лучше:

  1. it() должно волшебным образом поддерживать async..await и обернуть мой обратный вызов в async() , чтобы мне не приходилось думать об этом.
  2. it() должен принимать необязательный параметр функции (т. Е. async или fakeAsync ), который завершит мой обратный вызов.
  3. it() должны существовать варианты ita() и itfa() , которые завершат мой обратный вызов соответствующим помощником async.
  4. it() завершает мой обратный вызов с помощью async , а дополнительный itf() завершит мой обратный вызов с помощью fakeAsync .

Мне не хватает существующей концепции или синтаксиса? Есть ли лучшая альтернатива?

     import { async } from '@angular/core/testing';

    describe('MyService', () => {
        let service: MyService;

        ...

        it('should get data', async( async() => {
            // arrange
            let expectedData = { answer: 42 };

            // act
            let data = await service.getDataAsync();

            // assert
            expect(data).toEqual(expectedData);
        } ));
    })
  

Комментарии:

1. Что касается «запутанности», может быть, теперь, когда они переименованы async() как waitForAsync() , это немного проще понять?

Ответ №1:

существует несколько различных способов обработки асинхронного тестирования:

  1. Используйте встроенную функцию karma doneFunction: (doneFunction) => {async test here... then eventually call done();} . Это дает вам точный контроль над тем, где заканчивается ваш тест, но заставляет вас как бы самостоятельно обрабатывать ошибки с помощью done.fail(error) .
  2. Завершите с помощью функции angular async(). Это часть вашего примера выше, но, как вы заметили, похоже, что функция Angular async автоматически не поддерживает синтаксис await внутри, что требует использования внутренней async для получения поддержки await.
  3. Используйте функцию-оболочку Angular fakeAsync(), которая позволяет вам вызывать tick() в любом месте вашего кода для имитации течения времени и разрешения наблюдаемых значений, обещаний и других асинхронных функций. Один недостаток: вы не можете выполнять HTTP-вызовы в этом, поскольку они будут выполняться в режиме реального времени.

Хотя я обнаружил, что у каждого из 3 методов есть свои плюсы и минусы, я обнаружил, что # 2 является наиболее полезным для создания плавного прохождения теста, который легко читается. Итак, хотя вы могли бы избежать вложенного асинхронного кода, используя # 1 или # 3, я не уверен, что выгода перевесит затраты. Что касается ваших предложений, вы можете рассмотреть возможность отправки запроса функции в репозиторий angular, если это важно для вас.

Для получения дополнительной информации я нашел этот источник весьма полезным: https://medium.com/@michaelericksen_12434/angular-asynchronous-test-patterns-and-recipes-202cf7d47ec7 . Надеюсь, это поможет!