Error: No provider for InjectionToken USE_DEFAULT_LANG

Vicky Singh Gill picture Vicky Singh Gill · Dec 8, 2017 · Viewed 8.5k times · Source

I am new to angular 4 jasmine unit testing.

  1. Kindly help me to get full test coverage for my component attached.
  2. I have added child dependencies for translate module but still I am getting Error: No provider for InjectionToken USE_DEFAULT_LANG! what is the solution for this???
  3. I want to know how to cover variables and methods in the code I attached for full coverage.

Thanks for helping.

LOGIN COMPONENT :

   import { Component, OnInit } from '@angular/core';
    import { Router } from '@angular/router';
    import { Http, Headers, RequestOptions, Response } from '@angular/http';
    import { HttpError } from '../core/http-error';
    import { jsonFields } from '../app.constants';
    import { LoggedUserData } from '../shared/model/loggedUserData';
    import { Observable } from 'rxjs/Observable';
    import { FormControl, Validators } from '@angular/forms';
    import { LoginService } from '../shared/login.service';

    @Component({
      selector: 'app-login',
      templateUrl: './login.component.html',
      styleUrls: ['./login.component.scss']
    })
    export class LoginComponent implements OnInit {
      userID: string;
      userPassword: string;
      hide: boolean = true;
      errorMsg: string;
      errorShow: boolean = false;
      showLoad: boolean = false;

      constructor(private router: Router, private _http: Http, private _LoginService: LoginService) { }

      loginFormControl = new FormControl('', [
        Validators.required]);

      ngOnInit() {
      }
      onLogin() {
        this.showLoad = true;
        var loggedUserData = new LoggedUserData();
        var secPayload = {};
        secPayload[jsonFields.login.userId] = this.userID;
        secPayload[jsonFields.login.password] = this.userPassword;
        secPayload[jsonFields.login.businessUnitId] = "7238";
        secPayload[jsonFields.login.domainName] = "";

        this._LoginService.authenticate(secPayload).subscribe(
          result => {
            loggedUserData.userId = result[jsonFields.loggedUserData.userId];
            loggedUserData.token = result[jsonFields.loggedUserData.token];
            loggedUserData.authTypeCode = result[jsonFields.loggedUserData.authTypeCode];
            loggedUserData.businessUnitId = result[jsonFields.loggedUserData.businessUnitId];
            loggedUserData.firstName = result[jsonFields.loggedUserData.firstName];
            loggedUserData.lastName = result[jsonFields.loggedUserData.lastName];
            loggedUserData.links = result[jsonFields.loggedUserData.links];
            loggedUserData.locale = result[jsonFields.loggedUserData.locale];
            loggedUserData.pwdExpired = result[jsonFields.loggedUserData.pwdExpired];
            loggedUserData.securityId = result[jsonFields.loggedUserData.securityId];
            loggedUserData.upn = result[jsonFields.loggedUserData.upn];
            this.errorShow = false;
            const token: string = loggedUserData.token;
            if (token != null) {
              localStorage.setItem("tokenId", token);
              this.router.navigate(['delivery']);
            }
            else {
              localStorage.removeItem("tokenId");
              this.router.navigate(['login']);
            }
            this.showLoad = false;
          },
          (error: HttpError) => {
            this.errorShow = true;
            this.errorMsg = error.message;
            this.showLoad = false;
          }
        );
      }
    }

LOGIN COMPONENT SPEC :

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

import { LoginComponent } from './login.component';
import { LoginService } from '../shared/login.service';
import { MatProgressBarModule } from '@angular/material';
import { TranslateModule, TranslateService, TranslateLoader, TranslateFakeLoader, TranslateCompiler, TranslateParser, MissingTranslationHandler } from '@ngx-translate/core';
import { MatInputModule } from '@angular/material';
import { FormsModule } from '@angular/forms';
import { Router, RouterModule } from '@angular/router';
import { HttpModule } from '@angular/http';
import { TranslationService } from '../translation/translation.service';
import { TranslateStore } from "@ngx-translate/core/src/translate.store";


describe('LoginComponent', () => {
  let component: LoginComponent;
  let fixture: ComponentFixture<LoginComponent>;

  const mockLoginService = {
    authenticate() { },
    validateLoginToken() { }
  };

  const mockTranslationService = {
    validateLanguage() {
    }
  }

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [LoginComponent],
      imports: [MatProgressBarModule, FormsModule, HttpModule, RouterModule, TranslateModule],
      providers: [
        {
          provide: LoginService, useValue: mockLoginService
        },
        {
          provide: TranslationService, useValue: mockTranslationService
        },
        {
          provide: Router,
          useClass: class { navigate = jasmine.createSpy("navigate"); }
        },
        {
          provide: TranslateLoader,
          useClass: TranslateFakeLoader
        },
        TranslateService, TranslateStore, TranslateCompiler, TranslateParser, MissingTranslationHandler
      ]
    })
      .compileComponents();
  }));

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

  it('should create', () => {
    component.errorMsg = "dsadsad";
    component.errorShow = true;
    component.hide = true;
    component.showLoad = true;
    component.userID = '';
    component.userPassword = '';


    expect(component).toBeTruthy();
    expect(component.onLogin).toBeTruthy();

  });

  it('validate Login', inject([LoginService],
    (service: LoginService) => {
      expect(service.authenticate).toBeTruthy();
      expect(service.validateLoginToken).toBeTruthy();
    }));

  it('should translate the language service', inject([TranslationService],
    (service: TranslationService) => {
      expect(service).toBeTruthy();
      expect(service.validateLanguage).toBeTruthy();
    }));
});

TRANSLATION MODULE :

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';

import { HttpClientModule, HttpClient } from '@angular/common/http';
import { TranslateModule, TranslateLoader } from '@ngx-translate/core';
import { TranslateHttpLoader } from '@ngx-translate/http-loader';

// AoT requires an exported function for factories
export function HttpLoaderFactory(httpClient: HttpClient) {
  return new TranslateHttpLoader(httpClient, "./assets/i18n/", ".json");
}
@NgModule({
  imports: [
    CommonModule,
    HttpClientModule,
    TranslateModule.forRoot({
      loader: {
        provide: TranslateLoader,
        useFactory: HttpLoaderFactory,
        deps: [HttpClient]
      }
    })
  ],
  declarations: []
})
export class TranslationModule { }

Answer

CodeChimpy picture CodeChimpy · Dec 28, 2017

In your spec file add this provider to the config part of TestBed:

    beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [LoginComponent],
      imports: [MatProgressBarModule, FormsModule, HttpModule, RouterModule, TranslateModule],
      providers: [

        { provide: USE_DEFAULT_LANG }, // <== add this line

        {
          provide: LoginService, useValue: mockLoginService
        },
        {
          provide: TranslationService, useValue: mockTranslationService
        },
        {
          provide: Router,
          useClass: class { navigate = jasmine.createSpy("navigate"); }
        },
        {
          provide: TranslateLoader,
          useClass: TranslateFakeLoader
        },
        TranslateService, TranslateStore, TranslateCompiler, TranslateParser, MissingTranslationHandler
      ]
    })
      .compileComponents();
    }));

You also need this import:

import {USE_DEFAULT_LANG} from '@ngx-translate/core';

This should be added to the other imports from @ngx-translate/core