angular - 测试依赖于 2 个服务的组件
问题描述
我有一个使用服务来检索信息的组件。但是该服务还从静态变量 conf 中获取配置服务的配置。运行 karma 测试时,const 变量是未定义的。
我知道我可以创建模拟服务,但是我应该创建 2 个服务来测试这个组件吗?如果是的话,我还有其他服务也使用配置服务,所以我必须为每个服务创建模拟服务?似乎需要做很多工作,但我还没有找到更好的解决方案:(我提供了 ConfigurationService 和我正在使用的服务,如果这有什么不同的话。
TypeError: Cannot read property 'apiUrl' of undefined
apiUrl 是 conf 的一个属性,它是 ConfigurationService 中的一个静态变量。
配置服务.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;
}
}
信息服务.ts
export class InfoService {
private InfoUrl = ConfigService.conf.apiUrl + '/info';
constructor(private http: HttpClient) {}
getInfo(){
return http.get(InfoUrl);
}
}
信息组件.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();
});
});
解决方案
基本上你的组件需要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();
});
});
推荐阅读
- c++ - 隐式调用是什么意思?
- list - 从列表中创建一个虚线对列表,将其对数划分为另一个数
- c++ - 从私有成员变量的成员方法返回 unique_ptr
- spring - 导入 org.springframework.boot.actuate.metrics.CounterService 无法解析
- java - 低功耗蓝牙正在下降特性
- database - 是否可以在 SSIS 中加入合并相同的数据库列?
- android - 相机分辨率
- php - 在 Laravel 中查询按数组过滤的数据库
- java - 用于嵌入式 Tomcat 8.5 的 Tomcat Maven 插件
- c++ - 重载运算符有地址吗?