不带依赖的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 中弃用。
