Модульное тестирование в Angular 15 без TestBed
Преодоление разрыва между DI-тестированием на основе конструктора и DI-тестированием на основе внедрения без TestBed
В Angular 14 появилась возможность использовать функцию ввода в таких классах, как компоненты, директивы и каналы. Авторы библиотек приняли эту функцию , и многие отказались от внедрения зависимостей на основе конструктора ('DI'). Это также вдохновило на создание повторно используемых функций под названием DI Functions .
Существует множество подходов с использованием TestBed , которые позволяют тестировать и даже имитировать зависимости, предоставляемые функцией Inject.
Однако что, если вы не хотите использовать TestBed? Может быть, из-за проблем с производительностью , может быть, вы предпочитаете изолировать модульные тесты от DOM по умолчанию, или, может быть, вы заметили, что Angular вводит утилиты , облегчающие запуск функций в контексте внедрения с провайдерами.
тл; др:
- run
npm i @ngx-unit-test/inject-mocks -Dдля установки служебных функций для модульного тестирования любого класса или функции Angular без TestBed.
В этой статье (1) описывается компонент, требующий модульного тестирования, (2) демонстрируется, как тестировать этот компонент в Angular 15+ без TestBed, и (3) показано, как тестировать функцию DI без TestBed.
1. Настройка: компонент, который нуждается в модульном тестировании
Вот простой HomeComponent, написанный на Angular 15, который использует функцию вставки:
Компонент внедряет WidgetsFacade, получает доступ к некоторым наблюдаемым объектам, предоставляемым этим фасадом, и запускает метод фасада во время ngOnInit.
2. Предоставление фиктивных зависимостей
Итак, как можно смоделировать внедрённый WidgetsFacade без использования TestBed?
Если вы просто запустите спецификацию без TestBed, вы получите эту ошибку:
Чтобы предоставить услугу и имитировать ее функции, необходимо выполнить два шага:
Во-первых, создайте служебный метод, который обертывает @angular/coreInjector:
Эта утилита использует встроенный Injectorкласс Angular для автоматического предоставления зависимостей данному классу. Вы можете заметить, что это имя classWithProviders, а не componentWithProviders. Это потому, что утилита работает с компонентами, службами, директивами и каналами!
Во-вторых, используйте classWithProvidersв файле спецификаций:
Давайте пройдемся по каждому шагу в файле спецификаций:
- Объявите переменную
facadeMockс типомPartial<WidgetsFacade>. Используйте Partial, чтобы получить определение типа на следующем шаге. - Назначить фиктивный объект : создайте объект JavaScript и назначьте
jest.fn()метод, который вам нужно имитировать. - Получить компонент с контекстом внедрения : благодаря утилите
classWithProvidersвозвращенный компонент имеет фиктивный провайдер!
Одним из ограничений classWithProvidersявляется то, что он не работает с функциями внедрения зависимостей (функциями DI). Текущее решение для тестирования функций DI включает в себя TestBed.runInInjectionContext, которое было выпущено в Angular 15.1.0 .
Опираясь на пример TestBed, можно создать автономную утилиту, которая предоставляет аналогичное решение для тестирования функций DI с фиктивными провайдерами:
Фактически, команда Angular уже работает над новой утилитой runInInjectionContext , которая заменяет и расширяет метод runInContext.
Заключение
Утилиты classWithProvidersи runFnInContextбыли вдохновлены кодом из исходного кода Angular.io . Я предпринял дополнительный шаг, объединив эти утилиты в пакет npm . Спасибо Джошу Ван Аллену и Рафаэлю Местре за их понимание и помощь в разработке этих утилит.
О HeroDevs
HeroDevs — студия разработки программного обеспечения и консалтинга, которая специализируется на фронтенд-разработке. Наша команда является автором или соавтором таких проектов, как Angular CLI, Angular Universal, Scully, XLTS — расширенная долгосрочная поддержка AngularJS, Vue2, Protractor и многих других. Мы работаем с быстрорастущими стартапами и некоторыми из крупнейших мировых компаний, такими как Google, GE, Capital One, Experian, T-Mobile, Corteva и другими. Узнайте больше о нас на сайте herodevs.com .

![В любом случае, что такое связанный список? [Часть 1]](https://post.nghiatu.com/assets/images/m/max/724/1*Xokk6XOjWyIGCBujkJsCzQ.jpeg)



































