Search code examples
angularunit-testingtransloco

How to correctly unit test labels coming from transloco api in angular


I have been using Transloco API for a time but I have not been able to use it during unit testing.

I am following this blog from ngneat Unit testing with transloco

But my simple test cases are also failing due to some reason with below error:

Chrome 83.0.4103 (Windows 10.0.0) AppComponent should render title in a h1 tag FAILED
        Error: Expected ' page-heading! ' to contain 'Welcome to transloco-sample!'.
            at <Jasmine>
            at UserContext.<anonymous> (http://localhost:9876/_karma_webpack_/src/app/app.component.spec.ts:40:54)
            at ZoneDelegate.invoke (http://localhost:9876/_karma_webpack_/node_modules/zone.js/dist/zone-evergreen.js:359:1)
            at ProxyZoneSpec.push../node_modules/zone.js/dist/zone-testing.js.ProxyZoneSpec.onInvoke (http://localhost:9876/_karma_webpack_/node_modules/zone.js/dist/zone-testing.js:308:1)

My config files and test suite are as follows :

transloco-root.module.ts

import { HttpClient } from '@angular/common/http';
import {
  TRANSLOCO_LOADER,
  Translation,
  TranslocoLoader,
  TRANSLOCO_CONFIG,
  translocoConfig,
  TranslocoModule
} from '@ngneat/transloco';
import { Injectable, NgModule } from '@angular/core';
import { environment } from '../environments/environment';

@Injectable({ providedIn: 'root' })
export class TranslocoHttpLoader implements TranslocoLoader {
  constructor(private http: HttpClient) { }

  getTranslation(lang: string) {
    return this.http.get<Translation>(`/assets/i18n/${lang}.json`);
  }
}

@NgModule({
  exports: [TranslocoModule],
  providers: [
    {
      provide: TRANSLOCO_CONFIG,
      useValue: translocoConfig({
        availableLangs: ['fr', 'en'],
        defaultLang: 'en',
        // Remove this option if your application doesn't support changing language in runtime.
        reRenderOnLangChange: true,
        prodMode: environment.production,
      })
    },
    { provide: TRANSLOCO_LOADER, useClass: TranslocoHttpLoader }
  ]
})
export class TranslocoRootModule { }

app.component.html

<div style="text-align:center">
  <h1>
    {{ 'page-heading' | transloco }}!
  </h1>
</div>

transloco-testing.module.ts

import { TranslocoTestingModule, TranslocoConfig } from '@ngneat/transloco';
import * as en from '../assets/i18n/en.json';
import * as fr from '../assets/i18n/fr.json';

export function getTranslocoModule(config: Partial<TranslocoConfig> = {}) {
    return TranslocoTestingModule.withLangs(
        { en, fr },
        {
            availableLangs: ['en', 'fr'],
            defaultLang: 'en',
            ...config
        }
    );
}

and

test suite as

import { TestBed, async } from '@angular/core/testing';
import { RouterTestingModule } from '@angular/router/testing';
import { AppComponent } from './app.component';
import { getTranslocoModule } from './transloco-testing.module';
import { LangDropDownComponent } from './lang-drop-down/lang-drop-down.component';

fdescribe('AppComponent', () => {

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      imports: [
        RouterTestingModule,
        getTranslocoModule()
      ],
      declarations: [
        AppComponent, LangDropDownComponent
      ],
    }).compileComponents();
  }));

  it('should create the app', () => {
    const fixture = TestBed.createComponent(AppComponent);
    const app = fixture.debugElement.componentInstance;
    expect(app).toBeTruthy();
  });

  it('should render title in a h1 tag', () => {
    const fixture = TestBed.createComponent(AppComponent);
    fixture.detectChanges();
    const compiled = fixture.debugElement.nativeElement;
    console.log(compiled.querySelector('h1').textContent);
    expect(compiled.querySelector('h1').textContent).toContain('Welcome to transloco-sample!');
  });
});

Also, en.json

{
    "application": "Transloco - Sample ",
    "title": "Testing Transloco",
    "para-title": "Here are some links to help you start: ",
    "page-heading": "Welcome to Transloco App",
    "client": {
        "name": "Name"
    }
}

I also have the following options in tsconfig.json:

"resolveJsonModule": true, "esModuleInterop": true

Can anyone suggest something?


Solution

  • Posting this answer, so it might help others.

    As per the documentation of transloco, we need to add the following parameter in tsconfig.json:

    {
      "resolveJsonModule": true,
      "esModuleInterop": true
    }
    

    And in many places, it was written that these need to be added in compiler options. But it did not work, so I tried to add them in the angularCompilerOptions in tsconfig.json and it worked fine.

    So I added them as below in my tsconfig.json :

      "angularCompilerOptions": {
        "fullTemplateTypeCheck": true,
        "strictInjectionParameters": true,
        "resolveJsonModule": true,
        "esModuleInterop": true
      }
    

    And it is working fine.