Ответ 1
Лучше вы можете попытаться преобразовать свой сервис в Тип, а затем использовать инжектор, например, так:
import { Type } from '@angular/core';
fixture.debugElement.injector.get<MyService>(MyService as Type<MyService>)
После перехода на Angular 5.2.3 и запуска ng cli
с правилом линтера "deprecation": true
во многих моих тестах я получаю следующую ошибку:
get is deprecated: from v4.0.0 use Type<T> or InjectionToken<T>
Жалоба похожа на
fixture.debugElement.injector.get(MyService)
с классом MyService
, используемым для внедрения зависимостей.
Я затрудняюсь догадаться, каким должен быть новый синтаксис, так как
fixture.debugElement.injector.get<MyService>(MyService)
выдает ошибку компиляции, которая Argument of type 'typeof MyService' is not assignable to parameter of type 'Type<MyService> | InjectionToken<MyService>'.
Как правильно использовать инжектор, чтобы избежать ошибок устаревания?
Изменение: см. ответ ниже, для обновления Angular9.
Редактировать: Кажется, это связано с MyService, являющимся абстрактным классом. Если я использую неабстрактный класс, синтаксис .get<T>(T)
работает.
Редактировать: Исправление, по-видимому, в ожидании некоторой работы PR - https://github.com/angular/angular/pull/25222
Лучше вы можете попытаться преобразовать свой сервис в Тип, а затем использовать инжектор, например, так:
import { Type } from '@angular/core';
fixture.debugElement.injector.get<MyService>(MyService as Type<MyService>)
В качестве временного решения вы можете попробовать следующее:
fixture.debugElement.injector.get<MyService>(MyService as any)
Я работал над этим, определяя токен ввода:
export const DATA_SERVICE = new InjectionToken('DataService');
и используя его для псевдонима моей службы в модуле:
...
providers = [
{ provide: DataService, useFactory: dataServiceFactory },
{ provide: DATA_SERVICE, useExisting: DataService }
]
...
Затем я могу получить эту услугу непосредственно из Injector
с помощью токена ввода, не получив предупреждения об устаревании:
this.dataService = injector.get(DATA_SERVICE);
В моем случае DataService
является абстрактным классом, и у меня есть две конкретные (@Injectable
) реализации для переключения между @Injectable
данными и реальными данными веб-сервиса. Соответствующая версия dataServiceFactory
методе dataServiceFactory
.
Есть две перегрузки для вызова injector.get()
и я думаю, что без InjectionToken
вызывается устаревшая перегрузка, потому что система типов не распознает тип typeof DataService
как InjectionToken
.
Интересно, что все инъекции этой услуги компонентам через конструкторы, такие как:
constructor(
ds: DataService
) { }
в настоящее время работаю. Будут ли они работать, когда устаревшая перегрузка get()
будет удалена в будущем?
Я думаю, что это вопрос для команды Angular.
ОБНОВЛЕНИЕ: для Angular9 синтаксис был изменен на следующий:
TestBed.inject<IDataService>(IDataService)
.
Это также работает для абстрактных классов.
В VSCode вы можете исправить большинство ваших случаев с помощью этого
FIND: TestBed.get\(([^\)]+)\) as .*;
REPLACE: TestBed.inject<$1>($1);
PRE Angular 9. Так что, похоже, это связано с абстрактными и неабстрактными классами.
Я разместил свои выводы здесь: https://github.com/angular/angular/issues/22063 на случай, если кто-то столкнется с той же проблемой.
Я продолжал получать это предупреждение, даже если я изменил код в соответствии с недревесенным get(). После обновления Angular CLI с 6.0.0. 6.2.6 предупреждение ушло.