测试依赖于2个服务的组件

时间:2019-06-08 12:52:35

标签: angular typescript karma-jasmine

我有一个使用服务来检索信息的组件。但是该服务还从静态变量conf中从配置服务获取配置。运行业力测试时,const变量未定义。

我知道我可以创建模拟服务,但是我应该创建2个服务来测试此组件吗?如果是的话,我还有其他也使用配置服务的服务,那么我必须为每个服务创建模拟服务吗?似乎需要大量工作,但我还没有找到更好的解决方案:( 我提供了ConfigurationService和我正在使用的服务,如果这有任何区别。

TypeError: Cannot read property 'apiUrl' of undefined

apiUrl是conf的属性,它是ConfigurationService中的静态变量。

ConfigService.ts

import {Injectable} from '@angular/core';
import {HttpClient} from '@angular/common/http';

import * as YAML from 'js-yaml';
import {Config} from './models/Config';


@Injectable()
export class ConfigService {
  public static  conf: Config;

  constructor(private http: HttpClient) {}
   async load() {
       const res = await this.http.get<Config>('assets/config.yml', {responseType: 'text' as 'json'}).toPromise();
       ConfigService.conf = YAML.load(res).environment;
  }
}

InfoService.ts

export class InfoService {
  private InfoUrl = ConfigService.conf.apiUrl + '/info';

  constructor(private http: HttpClient) {}
  getInfo(){
    return http.get(InfoUrl);
  }
}

InfoComponent.ts

export class InfoComponent implements OnInit {
  private info;
  constructor(private infoService: InfoService) {}

  ngOnInit() {}

  loadInfo() {
    this.info = this.infoService.getInfo();
  }

InfoComponent.spec.ts

import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { InfoComponent } from './info.component';
import {HttpClientModule} from '@angular/common/http';
import {InfoService} from './info.service';
import {ConfigService} from '../shared/config.service';


describe('InfoComponent', () => {
  let component: InfoComponent;
  let fixture: ComponentFixture<InfoComponent>;

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      imports: [HttpClientModule],
      declarations: [InfoComponent],
      providers: [
          ConfigService
          InfoService,
      ],
    })
    .compileComponents();
  }));

  beforeEach(() => {
    fixture = TestBed.createComponent(InfoComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

   it('should create', () => {
     expect(component).toBeTruthy();
   });
});

1 个答案:

答案 0 :(得分:1)

基本上,您的组件需要InfoService。单元测试的核心概念围绕隔离目标代码并对其进行测试。因此,就您而言,您无需创建对ConfigService的依赖关系。应该有一个单独的单元测试来测试ConfigService

的行为
class InfoServiceStub {
  getInfo(){
    return of({
        /// your mock data
     });
  }
}


describe('InfoComponent', () => {
  let component: InfoComponent;
  let fixture: ComponentFixture<InfoComponent>;

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      imports: [HttpClientModule],
      declarations: [InfoComponent],
      providers: [
          {provide: InfoService, useClass: InfoServiceStub },
      ],
    })
    .compileComponents();
  }));

  beforeEach(() => {
    fixture = TestBed.createComponent(InfoComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

   it('should create', () => {
     expect(component).toBeTruthy();
   });
});