我尝试创建一个与AppLoaderService
匹配的假服务,用于我的Angular应用程序的业力测试。
我有一个服务,可以处理我的应用程序的加载器可见性状态。它以这种方式用于组件:
emitChange
功能来更改服务的可见性状态这是服务:
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Rx';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
@Injectable()
export class AppLoaderService {
private isLoaderVisible = new BehaviorSubject<boolean>(false);
changeLoaderState$ = this.isLoaderVisible.asObservable();
emitChange(state: any) {
this.isLoaderVisible.next(state);
}
}
事实上,团队会随着时间的推移改变这项服务。
我并不真正关心测试AppLoaderService的逻辑在组件测试级别“工作”的事实。我只希望能够在组件级别测试订阅服务(对于主要组件)并返回初始服务值,并且在我的组件生命周期中的某些时刻触发了emitChange()
。
因此,为了不依赖于服务本身,也许我可以将此服务存根到那时,在我的组件测试中,能够使用此存根:
providers: [
{provide: AppLoaderService, useClass: AppLoaderServiceStub}
]
但是我很难在不重写整个服务的情况下定义合适的存根。
您对我如何实现这一目标有任何想法吗?特别是我的一个组件正在订阅changeLoaderState$
。
答案 0 :(得分:2)
存根时的关键点是存根需要实现被测组件所关心的公共API 。
从您的示例代码中,您需要在存根上使用emitChange(state: any)
方法。如果你根本不关心它是否被调用,那么你可以将该方法留空。
export class AppLoaderServiceStub {
emitChange(state: any) {
}
}
(我假设服务上的observable属性仅由您的Loader组件使用,而不是由您的应用程序的其他组件和服务使用 - 如果该假设是错误的,您将拥有以及那个可观察的存根。)
修改强>
因为你需要changeLoaderState $ observable,那么那个存根 -
export class AppLoaderServiceStub {
changeLoaderState$ = Observable.of({ }) // or whatever dummy state value you want to use
emitChange(state: any) {}
}
请注意Observable.of
将发出其值然后完成。如果您不想触发完成事件,则可能需要Observable.never
。如果我正确理解你的用法,我怀疑这种区别是否重要。
PS。不要忘记导入of
运算符:
import 'rxjs/add/observable/of';