服务通常是单元测试中最简单的文件类型
对于一个没有其他依赖的服务,Mock 一些数据,进行测试即可
例如:对于一个公共数据处理的服务
import {Injectable} from '@angular/core';
import {Subject} from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class PublicDataService {
private themeColor = null;
private tenementList: Array<any>; // 租户List
public themeSubject = new Subject<any>();
constructor() {
}
// tenementList Set方法 -- 用于从projectindex -> myproject 中
public setTenementList(list): void {
this.tenementList = list;
const tenementhandledList = [];
this.tenementList.forEach(tenement => {
const projectList = [];
tenement.comSystems.forEach(project => {
const projectObject = {
value: project.id,
label: String(project.tagName).toUpperCase() + '-' + project.projectName,
isLeaf: true
};
projectList.push(projectObject);
});
const tenementObject = {
value: tenement.id,
label: tenement.tenantName,
children: projectList,
};
tenementhandledList.push(tenementObject);
});
this.tenementList = tenementhandledList;
}
// tenementList Get方法 -- 用于从projectindex -> myproject 中
public getTenementList(): Array<any> {
return this.tenementList;
}
// 设置主题
public setTheme(theme: string): void {
switch (theme) {
case '0':
this.themeColor = 'green-theme';
break;
case '1':
this.themeColor = 'blue-theme';
break;
case '2':
this.themeColor = 'red-theme';
break;
}
window.localStorage.setItem('platformTheme', this.themeColor);
this.themeSubject.next(this.themeColor);
}
public getTheme(): string {
return this.themeColor;
}
}
在测试文件中,既可以使用TestBed创建一个 服务的实例进行测试,也可以直接 new 一个实例出来进行测试。
import {TestBed} from '@angular/core/testing';
import {PublicDataService} from './public-data.service';
describe('PublicDataService', () => {
let publicDataService: PublicDataService;
beforeEach(() => {
publicDataService = new PublicDataService();
TestBed.configureTestingModule({});
});
it('should be created', () => {
const service: PublicDataService = TestBed.get(PublicDataService);
expect(service).toBeTruthy();
});
it('should test function setTheme is green-theme', () => {
publicDataService.setTheme('0');
expect(window.localStorage.getItem('platformTheme')).toBe('green-theme');
expect(publicDataService.getTheme()).toBe('green-theme');
publicDataService.themeSubject.subscribe(theme => {
expect(theme).toBe('green-theme');
});
});
it('should test function setTheme is blue-theme', () => {
publicDataService.setTheme('1');
expect(window.localStorage.getItem('platformTheme')).toBe('blue-theme');
expect(publicDataService.getTheme()).toBe('blue-theme');
publicDataService.themeSubject.subscribe(theme => {
expect(theme).toBe('blue-theme');
});
});
it('should test function setTheme is red-theme', () => {
publicDataService.setTheme('2');
expect(window.localStorage.getItem('platformTheme')).toBe('red-theme');
expect(publicDataService.getTheme()).toBe('red-theme');
publicDataService.themeSubject.subscribe(theme => {
expect(theme).toBe('red-theme');
});
});
});
it('should be created', () => {
const service: PublicDataService = TestBed.get(PublicDataService);
expect(service).toBeTruthy();
});
在这里通过 TestBed 的 get() 方法去创建了一个PublicDataService类型的service,然后在断言service的可否正确创建。
it('should test function setTheme is green-theme', () => {
publicDataService.setTheme('0');
expect(window.localStorage.getItem('platformTheme')).toBe('green-theme');
expect(publicDataService.getTheme()).toBe('green-theme');
publicDataService.themeSubject.subscribe(theme => {
expect(theme).toBe('green-theme');
});
});
这里的 publicDataService 是在 beforeEach 的函数中创建出来的
beforeEach(() => {
publicDataService = new PublicDataService();
TestBed.configureTestingModule({});
});
然后使用 publicDataService 去调用服务里的方法,然后进行测试用例的断言。
在有些服务中,会涉及到其他注入到构造函数中的服务,在进行单元测试的时候,需要手工创建并注入这些依赖。
例如:
export class PublicDataService {
private themeColor = null;
constructor(private utilService: UtilService) {
}
public getLogoName() {
return this.utilService.getLogoNameWithUtil();
}
}
在测试的时候,如何创建呢?
it('should test function setPipeLineId', () => {
const publicDataServiceNoBed: PublicDataService = new PublicDataService(new UtilService());
publicDataServiceNoBed.setPipeLineId(1);
expect(publicDataServiceNoBed.getPipeLineId()).toBe(1);
});
it('# getLogoNameWithUtil should return faked value from a fake object', () => {
const fake = {getLogoNameWithUtil: () => 'fake value'};
const publicDataServiceAsFake = new PublicDataService(fake as UtilService);
expect(publicDataServiceAsFake.getLogoName()).toBe('fake value');
});
需要注意的是:fake中伪造的对象是依赖服务中的方法。getLogoNameWithUtil是UtilService中的方法
it('#getLogoNameWithUtil should return stubbed value from a spy', () => {
const valueServiceSpy = jasmine.createSpyObj('UtilService', ['getLogoNameWithUtil']);
const stubValue = 'UtilService stub value';
valueServiceSpy.getLogoNameWithUtil.and.returnValue(stubValue);
const publicDataServiceAsSpy = new PublicDataService(valueServiceSpy);
expect(publicDataServiceAsSpy.getLogoName())
.toBe(stubValue, 'service returned stub value');
expect(valueServiceSpy.getLogoNameWithUtil.calls.count())
.toBe(1, 'spy method was called once');
expect(valueServiceSpy.getLogoNameWithUtil.calls.mostRecent().returnValue)
.toBe(stubValue);
});
valueServiceSpy 是jasmine.createSpyObj是以UtilService为基础和getLogoNameWithUtil的方法名创建的对象。
calls.count() 返回spy调用的次数
calls.mostRecent() 以对象形式返回最近一次调用的上下文(this),以及传递的参数
需要注意的是,在使用jasmine.createSpyObj创建的时候,记得将UtilService 添加到providers数组中
TestBed.configureTestingModule({
providers: [UtilService],
});