ngx-translate立即函数不是抛出的函数:单元测试 [英] ngx-translate instant function is not a function thrown: Unit testing

查看:75
本文介绍了ngx-translate立即函数不是抛出的函数:单元测试的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对于单元测试和Angular,我还很陌生,我正在尝试为我的项目编写一些单元测试.

I'm fairly new for unit testing and Angular, and i'm trying to write some unit tests for my project.

我得到的错误是;

Uncaught TypeError: _this.translate.instant is not a function thrown
Expected null to be truthy.

component.spec文件的导入包括

The imports of the component.spec file includes

beforeEach(async(() => {
TestBed.configureTestingModule({
  imports:[
    ClarityModule,
    RouterTestingModule,
    TranslateModule.forRoot({
      loader: {
        provide: TranslateLoader,
        useFactory: (http: HttpClient) => new TranslateHttpLoader(http, 'assets/i18n/', '.json'),
        deps: [HttpClient]
      }
    }),
    HttpClientModule
  ],
  declarations: [
    HeaderComponent,
    LanguageSelectorComponent
  ],
  providers: [
    { provide: Store, useClass: TestStore },
    { provide: TranslateService, useClass: TranslateServiceStub },
    { provide: NGXLogger, useClass: NGXLoggerMock }
  ]
})
.compileComponents();
}));

我知道TranslateServiceStub不包含即时"功能.这是此错误的原因吗?如果是这样,我该如何模拟translate.instant函数?

I understand that TranslateServiceStub does not include a 'instant' function. Is this the cause of this error? if so, how can i mock translate.instant function?

或者在调用即时方法之前,有什么方法可以将翻译文件加载到规范文件中吗?

Or is there any way to load the translations file in the spec file before instant method gets called?

任何建议都会大有帮助.非常感谢!

Any suggestion would be greatly helpful. Thanks a lot!

推荐答案

按照文档链接instant的返回类型是stringObject.

As per the documentation link, the return type of instant is either string or Object.

instant(key: string|Array<string>, interpolateParams?: Object): string|Object

export class TranslateServiceStub {
    instant(): string{
      // or put some logic to return Mock data as per the passed value from component
      //  (if being used at multiple places in the component)
      return "some_string";
    }
}

类似地,如果需要,您可以返回Object.

Similarly, you can return an Object, if required.

我使用instant()尝试了以下组件:

I tried below component using instant():

import { Component } from '@angular/core';
import { TranslateService } from '@ngx-translate/core';
import { Observable } from 'rxjs';

@Component({
    selector: 'app-root',
    template: `
        <div>
            <h2>{{ 'HOME.TITLE' | translate }}</h2>
            <label>
                {{ 'HOME.SELECT' | translate }}
                <select #langSelect (change)="translate.use(langSelect.value)">
                    <option *ngFor="let lang of translate.getLangs()" [value]="lang" [selected]="lang === translate.currentLang">{{
                        lang
                    }}</option>
                </select>
            </label>
            <br>
            {{name}}
        </div>
    `,
})
export class AppComponent {
    public name: string;

    constructor(public translate: TranslateService) {
        translate.addLangs(['en', 'fr']);
        translate.setDefaultLang('en');

        const browserLang = translate.getBrowserLang();
        translate.use(browserLang.match(/en|fr/) ? browserLang : 'en');
    }
    public ngOnInit(): void {
        this.translate.onLangChange.subscribe(() => {
            this.name = this.translate.instant('HOME.TITLE'); // <---- instant() used here
        });
    }
}

因此,我创建了一个spec文件为:

and accordingly, I created a spec file as:

import {HttpClient} from "@angular/common/http";
import {HttpClientTestingModule, HttpTestingController} from "@angular/common/http/testing";
import {async, TestBed, ComponentFixture} from '@angular/core/testing';
import {TranslateLoader, TranslateModule, TranslateService} from "@ngx-translate/core";
import {AppComponent} from './app.component';
import {HttpLoaderFactory} from "./app.module";

const TRANSLATIONS_EN = require('../assets/i18n/en.json');
const TRANSLATIONS_FR = require('../assets/i18n/fr.json');

describe('AppComponent', () => {
  let translate: TranslateService;
  let http: HttpTestingController;
  let fixture: ComponentFixture<AppComponent>;
  let app: AppComponent;

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [
        AppComponent
      ],
      imports: [
        HttpClientTestingModule,
        TranslateModule.forRoot({
          loader: {
            provide: TranslateLoader,
            useFactory: HttpLoaderFactory,
            deps: [HttpClient]
          }
        })
      ],
      providers: [TranslateService]
    }).compileComponents();
    translate = TestBed.get(TranslateService);
    http = TestBed.get(HttpTestingController);
    fixture = TestBed.createComponent(AppComponent);
    app = fixture.componentInstance;
  }));

  it('should create the app', async(() => {
    expect(app).toBeTruthy();
  }));

  it('should load translations', async(() => {
    spyOn(translate, 'getBrowserLang').and.returnValue('en');
    const compiled = fixture.debugElement.nativeElement;

    // the DOM should be empty for now since the translations haven't been rendered yet
    expect(compiled.querySelector('h2').textContent).toEqual('');

    http.expectOne('/assets/i18n/en.json').flush(TRANSLATIONS_EN);
    http.expectNone('/assets/i18n/fr.json');

    // Finally, assert that there are no outstanding requests.
    http.verify();

    fixture.detectChanges();
    // the content should be translated to english now
    expect(compiled.querySelector('h2').textContent).toEqual(TRANSLATIONS_EN.HOME.TITLE);

    translate.use('fr');
    http.expectOne('/assets/i18n/fr.json').flush(TRANSLATIONS_FR);

    // Finally, assert that there are no outstanding requests.
    http.verify();

    // the content has not changed yet
    expect(compiled.querySelector('h2').textContent).toEqual(TRANSLATIONS_EN.HOME.TITLE);

    fixture.detectChanges();
    // the content should be translated to french now
    expect(compiled.querySelector('h2').textContent).toEqual(TRANSLATIONS_FR.HOME.TITLE);
    expect(app.name).toEqual('Bonjour Angular avec ngx-translate !');
  }));


});

我希望这可以帮助您更好地测试ng-translate.

I hope this will help you test ng-translate better.

这篇关于ngx-translate立即函数不是抛出的函数:单元测试的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆