如何使用Karma

时间:2017-04-08 17:13:40

标签: angular typescript

我尝试创建一个与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$

1 个答案:

答案 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';