ngx-translate立即函数不是抛出的函数:单元测试 [英] ngx-translate instant function is not a function thrown: Unit testing
问题描述
对于单元测试和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
的返回类型是string
或Object
.
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屋!