Angular单元测试报错TypeError: this.translate.get is not a function怎么解决?
解决Angular单元测试中
this.translate.get is not a function错误 错误信息
TypeError: this.translate.get is not a function at TranslatePipe.updateValue (http://localhost:9876/_karma_webpack_/webpack:/node_modules/@ngx-translate/core/__ivy_ngcc__/fesm2015/ngx-translate-core.js:1126:1) at TranslatePipe.transform (http://localhost:9876/_karma_webpack_/webpack:/node_modules/@ngx-translate/core/__ivy_ngcc__/fesm2015/ngx-translate-core.js:1167:1) at ɵɵpipeBind1 (http://localhost:9876/_karma_webpack_/webpack:/node_modules/@angular/core/fesm2015/core.mjs:22464:1) at LoginPageComponent_Template (ng:///LoginPageComponent.js:228:33)
问题背景
你在组件HTML中使用了translate管道:
<span class="close-button">{{ 'COMMON.CLOSE' | translate }}</span>
组件代码仅调用了TranslateService的use方法切换语言,但测试时出现上述错误。当前测试代码中创建了mock TranslateService,但只spy了use方法:
const mockTranslateService = jasmine.createSpyObj('TranslateService', ['use']); beforeEach(() => { TestBed.configureTestingModule({ declarations: [LoginModalComponent], imports: [ CommonModule, BrowserModule, TranslateModule.forRoot(), ReactiveFormsModule, UpgradeModule, ], providers: [ { provide: TranslateService, useValue: mockTranslateService }, /*Other services here...*/ ], }).compileComponents(); fixture = TestBed.createComponent(LoginModalComponent); component = fixture.componentInstance; });
组件代码:
constructor( private myService: MyService, private translateService: TranslateService ) {} ngOnInit(): void { const subscription = this.myService.fetchLanguage().subscribe((info) => { this.translateService.use(info.language.toLowerCase()); }); this.subscriptions.push(subscription); }
原因分析
Translate管道内部会调用TranslateService的get方法获取翻译文本,而你创建的mock对象只包含use方法的spy,未实现get方法,导致管道执行时触发错误。
解决方案
修改mock TranslateService,添加get方法的spy,并让它返回Observable(原get方法返回Observable类型):
// 导入rxjs的of操作符 import { of } from 'rxjs'; // 给spy对象添加get方法 const mockTranslateService = jasmine.createSpyObj('TranslateService', ['use', 'get']); // 模拟get方法的返回值,可自定义翻译结果 mockTranslateService.get.and.returnValue(of('关闭')); beforeEach(() => { TestBed.configureTestingModule({ declarations: [LoginModalComponent], imports: [ CommonModule, ReactiveFormsModule, UpgradeModule, // 测试环境已提供mock服务,可移除TranslateModule.forRoot()简化配置 // TranslateModule.forRoot(), ], providers: [ { provide: TranslateService, useValue: mockTranslateService }, /*Other services here...*/ ], }).compileComponents(); fixture = TestBed.createComponent(LoginModalComponent); component = fixture.componentInstance; });
补充说明
- 如果不需要特定翻译内容,也可让
get返回键名本身:mockTranslateService.get.and.returnValue(of('COMMON.CLOSE')) - 测试时无需引入
TranslateModule.forRoot(),通过provider提供mock服务即可,避免额外模块加载开销
内容的提问来源于stack exchange,提问作者zen zen
相关产品推荐
相关产品推荐

