title: Karma and Jasmine injected service test with Angular 7 - StaticInjectorError(DynamicTestModule)[I18n -> InjectionToken TranslationsFormat]
body: <p>This isn't a dupe of <a href="https://stackoverflow.com/questions/46740037/ngx-translate-no-provider-for-injectiontoken-documenttoken">ngx-translate - No provider for InjectionToken DocumentToken</a></p>
  
  <p>.... or <a href="https://stackoverflow.com/questions/49128781/angular5-ng-test-staticinjectorerror-from-custom-service">angular5 ng test - StaticInjectorError from custom service</a></p>
  
  <p>... and this is a slightly different issue that doesn't help me - <a href="https://github.com/ngx-translate/i18n-polyfill/issues/4" rel="nofollow noreferrer">https://github.com/ngx-translate/i18n-polyfill/issues/4</a></p>
  
  <hr>
  
  <p>I get the following error when I run <code>ngtest</code> using Jasmine and Karma:</p>
  
  <pre><code>Error: StaticInjectorError(DynamicTestModule)[I18n -&gt; InjectionToken TranslationsFormat]: 
    StaticInjectorError(Platform: core)[I18n -&gt; InjectionToken TranslationsFormat]: 
      NullInjectorError: No provider for InjectionToken TranslationsFormat!
  </code></pre>
  
  <p>I have a single test in my app, to test creation of the main data service:</p>
  
  <p><strong>data.service.spec.ts</strong></p>
  
  <pre><code>import { TestBed, inject } from '@angular/core/testing';
  
  import { DataService } from './data.service';
  import { I18n } from '@ngx-translate/i18n-polyfill';
  
  describe('DataService', () =&gt; {
    beforeEach(() =&gt; {
      TestBed.configureTestingModule({
        providers: [DataService, I18n]
      });
    });
  
    it('should be created', inject([DataService], (service: DataService) =&gt; {
      expect(service).toBeTruthy();
    }));
  });
  </code></pre>
  
  <p><strong>data.service.ts</strong></p>
  
  <pre><code>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 ...
    }
  
  }
  </code></pre>
  
  <p><strong>app.module.ts</strong></p>
  
  <pre><code>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) =&gt; {
          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 { }
  </code></pre>
  
  <p><strong>app.component.ts</strong></p>
  
  <pre><code>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
    }
  }
  </code></pre>
  
  <p><strong>UPDATE</strong></p>
  
  <p>If I alter the <code>data.service.ts</code> to add a TRANSLATIONS_FORMAT import as below, I get a different error:</p>
  
  <pre><code>Error: Invalid provider for the NgModule 'DynamicTestModule' - only instances of Provider and Type are allowed, got: [DataService, AuthService, I18n, ?InjectionToken TranslationsFormat?, ...]
  </code></pre>
  
  <hr>
  
  <pre><code>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', () =&gt; {
    beforeEach(() =&gt; {
      TestBed.configureTestingModule({
        providers: [DataService, AuthService, I18n, TRANSLATIONS_FORMAT]
      });
    });
  
    it('should be created', inject([DataService, AuthService, I18n, TRANSLATIONS_FORMAT], (service: DataService) =&gt; {
      expect(service).toBeTruthy();
    }));
  });
  </code></pre>