不带依赖的Service
Service不带有 constructor
或者 constructor
的不含参数的即为不带依赖的Service。如下方的CityService:
import { Injectable } from '@angular/core';
import { Subject } from 'rxjs';
@Injectable()
export class CityService {
private city: string;
citySubject = new Subject<string>();
getCity() {
return this.city;
}
setCity(city: string) {
this.city = city;
this.citySubject.next(this.city);
}
getCitys() {
return ['北京','上海','广州','深圳'];
}
getObservableValue() {
return this.citySubject.asObservable();
}
getPromiseValue() {
return this.citySubject.toPromise();
}
}
使用new操作符即可创建该类Service的实例,并进行测试。
import { CityService } from "./city3.service"
describe('CityService', () => {
let service: CityService;
beforeEach(() => {
service = new CityService();
});
it('#getCities 应该返回城市列表', () => {
const cities = service.getCities();
expect(cities).toBeTruthy();
expect(cities.length).toBeGreaterThanOrEqual(1);
});
it('getObservableValue 能正确返回设置值', (done) => {
service.getObservableValue().subscribe(city => {
expect(city).toBe('广州');
done()
});
service.citySubject.next('广州');
});
it('#getPromiseValue 能正确返回设置值', done => {
service.getPromiseValue().then(city => {
expect(city).toBe('北京');
done();
});
service.citySubject.next('北京');
service.citySubject.complete();
});
});
带有依赖的Service
注入的Service依赖足够简单
describe('MasterService without Angular testing support', () => {
let masterService: MasterService;
it('#getValue should return real value from the real service', () => {
masterService = new MasterService(new ValueService());
expect(masterService.getValue()).toBe('real value');
});
it('#getValue should return faked value from a fake object', () => {
const fake = { getValue: () => 'fake value' };
masterService = new MasterService(fake as ValueService);
expect(masterService.getValue()).toBe('fake value');
});
it('#getValue should return stubbed value from a spy', () => {
const valueServiceSpy =
jasmine.createSpyObj('ValueService', ['getValue']);
const stubValue = 'stub value';
valueServiceSpy.getValue.and.returnValue(stubValue);
masterService = new MasterService(valueServiceSpy);
expect(masterService.getValue())
.toBe(stubValue, 'service returned stub value');
expect(valueServiceSpy.getValue.calls.count())
.toBe(1, 'spy method was called once');
expect(valueServiceSpy.getValue.calls.mostRecent().returnValue)
.toBe(stubValue);
});
});
使用 TestBed 测试服务
TestBed 是 Angular 测试实用工具中最重要的。 TestBed 创建了一个动态构造的 Angular 测试模块,用来模拟一个 Angular 的 @NgModule 。
TestBed.configureTestingModule() 方法接受一个元数据对象,它可以拥有@NgModule的大部分属性。
要测试某个服务,你可以在元数据属性 providers 中设置一个要测试或模拟的服务数组。
let masterService: MasterService;
let valueServiceSpy: jasmine.SpyObj<ValueService>;
beforeEach(() => {
const spy = jasmine.createSpyObj('ValueService', ['getValue']);
TestBed.configureTestingModule({
providers: [
MasterService,
{ provide: ValueService, useValue: spy }
]
});
masterService = TestBed.inject(MasterService);
valueServiceSpy = TestBed.inject(ValueService) as jasmine.SpyObj<ValueService>;
});
注意: TestBed.get() 已在 Angular 9 中弃用。