Как издеваться над службой @injected при тестировании компонента angular 2?

У меня есть компонент с подписью:

constructor(private loremApiService: LoremApiService,
      private ipsumService: IpsumService,
      private dolorService: DolorService,
      @Inject('sitService') private sitService: library.service.Service) {
}

Файл спецификации для компонента настроен с помощью:

let component: PowerBiReportComponent;
let fixture: ComponentFixture<TestingComponent>;
const mockLoremApi = { methodThatIsCalled: () => {} };
const mockIpsumService = { };
const mockSitService = { };

beforeEach(async(() => {
    TestBed.configureTestingModule({
        declarations: [ TestingComponent ],
        schemas: [ CUSTOM_ELEMENTS_SCHEMA ],
        providers: [
            { provide: LoremApiService, useValue: mockLoremApi },
            { provide: IpsumService, useValue: mockIpsumService },
            UnmockedService,
            { provide: library.service.Service, useValue: mockSitService }
        ]
    })
    .compileComponents();
}));

beforeEach(() => {
    fixture = TestBed.createComponent(TestingComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
});

Однако поставщик не используется из-за декоратора @Inject, тест не выполняется при запуске с:

Error: StaticInjectorError(DynamicTestModule)[sitService]: 
  StaticInjectorError(Platform: core)[sitService]: 
  NullInjectorError: No provider for sitService!

Как заставить TestingModule использовать mockSitService, несмотря на то, что в компоненте он @Injection?

Пробовали делать: { provide: 'sitService', useValue: mockSitService }?

Daniel W Strimpel 18.04.2018 18:09

@DanielWStrimpel К сожалению, неанонимный сервис импортируется с import * as library from 'sit-library';, поэтому я не могу быть таким конкретным. Кроме того, к сожалению, фактический Тип службы называется Service.

StuperUser 18.04.2018 18:20

Все, что находится в @Inject(...), должно быть тем, что указано как свойство provide. Более новые версии Angular требуют (или настоятельно рекомендуют?), Чтобы это были токены для инъекций angular.io/guide/dependency-injection#injectiontoken

Daniel W Strimpel 18.04.2018 18:24

@DanielWStrimpel Аааа, я изменил объект предоставления в тесте, чтобы он соответствовал методу инъекции в родительском модуле компонента. Теперь это ошибка с [object ErrorEvent] thrown, которая может быть частью фактического тестового кода, который не работает из-за нереализованного макета. Это может решить проблему

StuperUser 18.04.2018 18:36

проверьте мой ответ здесь stackoverflow.com/a/49842183/4399281 вы можете найти пример имитации службы

Fateh Mohamed 18.04.2018 18:37

@DanielWStrimpel Если вы добавите обеспечение соответствия токенов инъекций в модуле компонента и TestModule в качестве configureTestingModule в качестве ответа, я приму это

StuperUser 18.04.2018 18:55
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Angular и React для вашего проекта веб-разработки?
Angular и React для вашего проекта веб-разработки?
Когда дело доходит до веб-разработки, выбор правильного front-end фреймворка имеет решающее значение. Angular и React - два самых популярных...
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Мы провели Twitter Space, обсудив несколько проблем, связанных с последними дополнениями в Angular. Также прошла Angular Tiny Conf с 25 докладами.
Угловой продивер
Угловой продивер
Оригинал этой статьи на турецком языке. ChatGPT используется только для перевода на английский язык.
Мое недавнее углубление в Angular
Мое недавнее углубление в Angular
Недавно я провел некоторое время, изучая фреймворк Angular, и я хотел поделиться своим опытом со всеми вами. Как человек, который любит глубоко...
Освоение Observables и Subjects в Rxjs:
Освоение Observables и Subjects в Rxjs:
Давайте начнем с основ и постепенно перейдем к более продвинутым концепциям в RxJS в Angular
2
6
9 236
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Как указано в комментариях, Angular требует, чтобы любой токен в @Inject(...) был таким же, как и тот, который указан для свойства provide при настройке службы с DI Angular. Это также означает, что токен внедрения должен быть экспортирован за пределы модуля, чтобы другие могли использовать синтаксис @Inject().

Если услуга предоставляется так:

@NgModule({
    providers: [
        { provide: SERVICE_TOKEN, useClass: Service }
    ]
})

Затем @Inject() должен быть настроен следующим образом (с использованием того же токена инъекции):

constructor(@Inject(SERVICE_TOKEN) private service: Service) {
}

Итак, в своем тесте вы имитируете это через (опять же, используя тот же токен инъекции):

beforeEach(async(() => {
    TestBed.configureTestingModule({
        providers: [
            { provide: SOME_TOKEN, useValue: mockService }
        ]
    })
    .compileComponents();
}));

Для получения дополнительной информации о токенах внедрения обратитесь к Документы по Angular.

Что делать, если у вас есть модуль, который использует forRoot для своих вводимых токенов, и вы хотите протестировать одну из служб внутри него, которая использует введенный токен? MyModule.forRoot(MyModuleConstants) имеет служебный MyModuleService и имеет constructor(@Inject(MyInjectionToken) constants)

EHorodyski 11.10.2018 00:39
useClass вместо useValue?
Gao Shenghan 21.07.2020 23:55

@GaoShenghan синтаксис зависит от того, что вы предоставляете. При настройке в модуле он использует useClass, поэтому Angular создает экземпляр для вас. В тесте OP имеет переменные, которые являются экземплярами зарезервированных сервисов, поэтому для них вы должны использовать версию useValue синтаксиса provide.

Daniel W Strimpel 22.07.2020 00:17

Другие вопросы по теме