错误:没有提供者注入FeedToken USE_DEFAULT_LANG

时间:2017-12-08 10:45:58

标签: angular jasmine karma-jasmine karma-coverage angular4-router

我是角度4茉莉花单元测试的新手。

  1. 请帮助我获得所附组件的完整测试覆盖率。
  2. 我为翻译模块添加了子依赖项,但我仍然得到错误:没有提供者注入FeedToken USE_DEFAULT_LANG!这是什么解决方案???
  3. 我想知道如何覆盖我附加的代码中的变量和方法以进行全面覆盖。
  4. 感谢您的帮助。

    登录组件:

       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;
              }
            );
          }
        }
    

    登录组件规范:

    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();
        }));
    });
    

    翻译模块:

    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 { }
    

1 个答案:

答案 0 :(得分:2)

在您的spec文件中,将此提供程序添加到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();
}));

您还需要此导入:

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

这应该添加到@ngx-translate/core

的其他导入中