Angular 对使用 TranslateService 的服务进行单元测试

Angular unit tests for services that uses TranslateService

如何在服务的单元测试中使用 TranslateService? TranslateService 以这种方式在服务 class 中使用:

export class ErrorControllerService {
    constructor(public translate: TranslateService) {
    }
    ...
}

我尝试以这种方式配置 TestingModule TestBed:

import { MyService } from './myservice';
import { TestBed } from '@angular/core/testing';

describe('MyService', () => {
  let myService:MyService;
  beforeEach(() => {
    TestBed.configureTestingModule({
      declarations: [ ],
      imports: [
                TranslateModule.forRoot({
                    loader: {
                        provide: TranslateLoader,
                        useFactory: HttpLoaderFactory,
                        deps: [HttpClient]
                    }
                    }),
      ],
      providers: [ MyService, TranslateService ],
    });
    let myService = TestBed.get(MyService);
  });

  it('should be created', () => {
    expect(myService).toBeDefined();
  });
});

npm 测试 的 运行 期间,我收到此消息

NullInjectorError: StaticInjectorError(DynamicTestModule)[TranslateService]: 
  StaticInjectorError(Platform: core)[TranslateService]: 
    NullInjectorError: No provider for TranslateService!
error properties: Object({ ngTempTokenPath: null, ngTokenPath: [ Function ] })
    at <Jasmine>
    at NullInjector.get (http://localhost:9876/_karma_webpack_/node_modules/@angular/core/fesm2015/core.js:778:1)
    at resolveToken (http://localhost:9876/_karma_webpack_/node_modules/@angular/core/fesm2015/core.js:2564:1)
    at tryResolveToken (http://localhost:9876/_karma_webpack_/node_modules/@angular/core/fesm2015/core.js:2490:1)
    at StaticInjector.get (http://localhost:9876/_karma_webpack_/node_modules/@angular/core/fesm2015/core.js:2353:1)
    at resolveToken (http://localhost:9876/_karma_webpack_/node_modules/@angular/core/fesm2015/core.js:2564:1)
    at tryResolveToken (http://localhost:9876/_karma_webpack_/node_modules/@angular/core/fesm2015/core.js:2490:1)
    at StaticInjector.get (http://localhost:9876/_karma_webpack_/node_modules/@angular/core/fesm2015/core.js:2353:1)
    at resolveNgModuleDep (http://localhost:9876/_karma_webpack_/node_modules/@angular/core/fesm2015/core.js:26403:1)
    at NgModuleRef_.get (http://localhost:9876/_karma_webpack_/node_modules/@angular/core/fesm2015/core.js:27491:1)
    at injectInjectorOnly (http://localhost:9876/_karma_webpack_/node_modules/@angular/core/fesm2015/core.js:657:1)

知道吗,我做错了什么?我的研究只向我展示了带有组件的示例,而不是带有服务的示例。

我想我是从 SO 上的另一个答案那里得到的,但我找不到它,所以...

解决方案是构建您的 TranslateTestingModule

我有 pipe 的模拟,并且 service 的不同功能到目前为止对我来说很神奇。

import { Injectable, NgModule, Pipe, PipeTransform } from '@angular/core';
import {
  TranslateLoader,
  TranslateModule,
  TranslatePipe,
  TranslateService
} from '@ngx-translate/core';

import { Observable, of } from 'rxjs';

const translations: any = {};

class FakeLoader implements TranslateLoader {
  getTranslation(lang: string): Observable<any> {
    return of(translations);
  }
}

@Pipe({
  name: 'translate'
})
export class TranslatePipeMock implements PipeTransform {
  public name = 'translate';

  public transform(query: string, ...args: any[]): any {
    return query;
  }
}

@Injectable()
export class TranslateServiceStub {
  public get<T>(key: T): Observable<T> {
    return of(key);
  }

  public getBrowserLang() {
    return 'es';
  }

  public setDefaultLang(language) {}

  public get currentLang() {
    return 'en';
  }

  public instant(key) {
    return 'value';
  }

  public use(lang) {}
}

@NgModule({
  declarations: [TranslatePipeMock],
  providers: [
    { provide: TranslateService, useClass: TranslateServiceStub },
    { provide: TranslatePipe, useClass: TranslatePipeMock }
  ],
  imports: [
    TranslateModule.forRoot({
      loader: { provide: TranslateLoader, useClass: FakeLoader }
    })
  ],
  exports: [TranslatePipeMock, TranslateModule]
})
export class TranslateTestingModule {}

然后您只需将其添加到测试模块的 imports 部分