Sergey
Sergey

Reputation: 7682

ngx-translate how to test components

I've got an application which uses this library. How do I test components with it? I DO NOT WANT TO TEST THE LIBRARY. I just need to start tests of my component without multiple errors about TranslateModule then TranslateService then TranslateStore ... until I get an error when compiling.

Is there an easy way to just run my tests with this dependency?

Once more, I don't want to test this library (check whether the string is being translated) I need to run tests on components which rely on this library.

Upvotes: 23

Views: 36386

Answers (4)

wutzebaer
wutzebaer

Reputation: 14865

For me the ngx-translate-testing worked well https://www.npmjs.com/package/ngx-translate-testing

first

import { TranslateTestingModule } from 'ngx-translate-testing';

then

  imports: [
    ...
    TranslateTestingModule.withTranslations({ en: require('src/assets/i18n/en.json'), de: require('src/assets/i18n/de.json') })
  ], 

then test

  it('should render german title', inject([TranslateService], (translateService: TranslateService) => {
    translateService.setDefaultLang('de');
    const fixture = TestBed.createComponent(AppComponent);
    fixture.detectChanges();
    const compiled = fixture.debugElement.nativeElement;
    expect(compiled.querySelector('.title').textContent).toContain('GERMANTITLE');
  }));

Upvotes: 24

Katja
Katja

Reputation: 867

(Tested with Angular 8.1.0 and ngx-translate 11.0.1)

A) If you use the translate pipe in your component, create a TranslateMockPipe and add it to the declarations array of your spec (as proposed in this issue).

translate-mock.pipe.ts

import {Pipe, PipeTransform} from '@angular/core';


@Pipe({
  name: "translate"
})
export class TranslateMockPipe implements PipeTransform {
  public name: string = "translate";

  public transform(query: string, ...args: any[]): any {
    return query;
  }
}

your-component.spec.ts

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [ YourComponent, TranslateMockPipe ],
      imports: [
        ...
      ]
    })
    .compileComponents();
  }));

In one case for some reason I also had to do step B).

B) If you use the translate service directly in your component, e.g. this.translate.get('foo.bar'), you'll need to import the TranslateModule and use the ngx-translate TranslateFakeLoader as a loader for it.

your-component.spec.ts

import {TranslateFakeLoader, TranslateLoader, TranslateModule} from '@ngx-translate/core';
...
  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [ YourComponent ], // you may add TranslateMockPipe from step 1 here, too
      imports: [
        ...
        TranslateModule.forRoot({
          loader: {
            provide: TranslateLoader,
            useClass: TranslateFakeLoader
          }
        })
      ]
    })
    .compileComponents();
  }));

This way, you can use the ngx-translate built-in Stub instead of creating your own as proposed in issue (it didn't work for me either).

Upvotes: 20

Chantal
Chantal

Reputation: 1059

If you don't necessarily need the keys to be translated you can import the TranslateModule in your test like this:

beforeEach(async(() => {
  TestBed.configureTestingModule({
    declarations: [
      ...
    ],
    imports: [
      TranslateModule.forRoot(),
    ],
    providers: [
      ...
    ]
  })
  .compileComponents();
}));

It will only show the translation keys

Upvotes: 36

Daniel B
Daniel B

Reputation: 8879

What I've done is to setup all my translation related configuration in a separate TranslationModule that I import to a SharedModule.

import { TranslateModule, TranslateLoader } from '@ngx-translate/core';

@NgModule({
  declarations: [],
  imports: [CommonModule,
    TranslateModule.forRoot({
      loader: {
        provide: TranslateLoader,
        useFactory: IfYouHaveACustomFactory,
        deps: [HttpClient]
      }
    })],
  exports: [TranslateModule],
  providers: [],
})
export class TranslationModule {

}

This can then be exported to all components that import the SharedModule,

@NgModule({
  imports: [],
  exports: [TranslationModule, SomeOtherModule],
})
export class SharedModule { }

And in your spec-file you simply import the SharedModule in your TestBed.configureTestingModule() like

 beforeEach(async(() => {
    TestBed.configureTestingModule({
      imports: [
        RouterTestingModule,
        SharedModule,
...

And tests for components that use the translation service or pipe should run fine!

Upvotes: 0

Related Questions