【问题标题】:Karma and Jasmine injected service test with Angular 7 - StaticInjectorError(DynamicTestModule)[I18n -> InjectionToken TranslationsFormat]使用 Angular 7 进行 Karma 和 Jasmine 注入服务测试 - StaticInjectorError(DynamicTestModule)[I18n -> InjectionToken TranslationsFormat]
【发布时间】:2020-01-08 21:48:32
【问题描述】:

这不是ngx-translate - No provider for InjectionToken DocumentToken的骗子

....或angular5 ng test - StaticInjectorError from custom service

...这是一个稍微不同的问题,对我没有帮助 - https://github.com/ngx-translate/i18n-polyfill/issues/4


当我使用 Jasmine 和 Karma 运行 ngtest 时出现以下错误:

Error: StaticInjectorError(DynamicTestModule)[I18n -> InjectionToken TranslationsFormat]: 
  StaticInjectorError(Platform: core)[I18n -> InjectionToken TranslationsFormat]: 
    NullInjectorError: No provider for InjectionToken TranslationsFormat!

我的应用中有一个测试,用于测试主数据服务的创建:

data.service.spec.ts

import { TestBed, inject } from '@angular/core/testing';

import { DataService } from './data.service';
import { I18n } from '@ngx-translate/i18n-polyfill';

describe('DataService', () => {
  beforeEach(() => {
    TestBed.configureTestingModule({
      providers: [DataService, I18n]
    });
  });

  it('should be created', inject([DataService], (service: DataService) => {
    expect(service).toBeTruthy();
  }));
});

data.service.ts

import { Injectable } from '@angular/core';
import { I18n } from '@ngx-translate/i18n-polyfill';


@Injectable({
  providedIn: 'root'
})
export class DataService {

  SOME_CONSTANT = this.i18n('Translate this text');

  constructor(private i18n: I18n, private authService: AuthService) {

    ...
  }

  public serviceMethod() {
    return ...
  }

}

app.module.ts

declare var require: any;

import { BrowserModule } from '@angular/platform-browser';
import { NgModule, LOCALE_ID, TRANSLATIONS, TRANSLATIONS_FORMAT } from '@angular/core';
import { HttpClientModule } from '@angular/common/http';
import { I18n } from '@ngx-translate/i18n-polyfill'; // polyfill to support i18n for text in .ts files (until supported by Angular)
import { AppComponent } from './app.component';
import { AppRoutingModule } from './app-routing.module';
import { LocaleService} from './services/locale.service';
import { SharedModule } from './shared/shared.module';
import { CoreModule } from './core/core.module';

defineLocale('engb', enGbLocale);
defineLocale('de', deLocale);
defineLocale('es', esLocale);
defineLocale('fr', frLocale);
defineLocale('zhcn', zhCnLocale);
defineLocale('ru', ruLocale);

/*
export function localeFactory(): string {
  return LocaleDatePipe.localeId;
}
*/

export function selectedLocaleFactory(): string {
  const localeService = new LocaleService();
  return localeService.getCurrentLanguage();
}

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    HttpClientModule,
    CoreModule,
    SharedModule,
    AppRoutingModule
  ],
  providers:
  [
    BsLocaleService,
    I18n,
    {
      provide: TRANSLATIONS,
      useFactory: (locale) => {
        locale = locale || 'en'; // default to english if no locale provided
        return require(`raw-loader!../locale/messages.${locale}.xlf`);
      },
      deps: [LOCALE_ID]
    },
    {
      provide: TRANSLATIONS_FORMAT,
      useValue: 'xlf'
    },
    {
      provide: LOCALE_ID,
      useFactory: selectedLocaleFactory
    }
  ],
  bootstrap: [AppComponent],
  entryComponents: [ConfirmationComponent]
})

export class AppModule { }

app.component.ts

import { Component, OnInit, OnDestroy } from '@angular/core';
import { DataService } from './services/data.service';

import { BsLocaleService } from 'ngx-bootstrap/datepicker';
import { LocaleService } from './services/locale.service';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit, OnDestroy {

  constructor(private dataService: DataService,
    private localeService: LocaleService,
    private bsLocaleService: BsLocaleService) { }

  ngOnInit() {

     ... nothing relevant
  }
}

更新

如果我更改 data.service.ts 以添加 TRANSLATIONS_FORMAT 导入,如下所示,我会收到不同的错误:

Error: Invalid provider for the NgModule 'DynamicTestModule' - only instances of Provider and Type are allowed, got: [DataService, AuthService, I18n, ?InjectionToken TranslationsFormat?, ...]

import { TestBed, inject } from '@angular/core/testing';

import { DataService } from './data.service';
import { AuthService } from './auth.service';
import { I18n } from '@ngx-translate/i18n-polyfill';
import { TRANSLATIONS, TRANSLATIONS_FORMAT } from '@angular/core';

describe('DataService', () => {
  beforeEach(() => {
    TestBed.configureTestingModule({
      providers: [DataService, AuthService, I18n, TRANSLATIONS_FORMAT]
    });
  });

  it('should be created', inject([DataService, AuthService, I18n, TRANSLATIONS_FORMAT], (service: DataService) => {
    expect(service).toBeTruthy();
  }));
});

【问题讨论】:

  • 在 data.service.spec.ts 的提供者中添加 TRANSLATIONS_FORMAT
  • @AjayReddy - 谢谢,虽然没用 - 请在问题底部查看我的更新

标签: angular karma-jasmine angular-test


【解决方案1】:

spec文件中尝试{provide: TRANSLATIONS_FORMAT, useValue: 'xlf' }如下:

 TestBed.configureTestingModule({
    providers: [DataService, AuthService, I18n, 
      {provide: TRANSLATIONS_FORMAT, useValue: 'xlf' }]
  });

【讨论】:

    【解决方案2】:

    有关 OP 的答案,请参阅@ShashankVivek 的答案。如果您收到与TRANSLATIONS 相关的后续错误,您将需要以下内容:

    describe('DataService', () => {
      beforeEach(() => {
        TestBed.configureTestingModule({
          providers: [DataService, AuthService, I18n, 
            {provide: TRANSLATIONS_FORMAT, useValue: 'xlf' },
            {provide: TRANSLATIONS, useValue: 'xlf' }
          ]
        });
      });
    

    【讨论】:

      猜你喜欢
      • 2016-12-21
      • 2023-03-18
      • 1970-01-01
      • 2017-06-10
      • 1970-01-01
      • 2020-03-14
      • 1970-01-01
      • 2020-04-10
      • 1970-01-01
      相关资源
      最近更新 更多