单元测试Observable.interval

时间:2017-05-29 07:04:25

标签: angular jasmine rxjs

我有一个轮询api的函数,直到返回所需的结果或者直到达到超时时间。

// sample poll, filter and timeout
   pollStatus = (): Observable<string> => {
            return Observable.interval(1000)
              .mergeMap(() => this.getStatus(); // this makes a http call to a status api
              .map((response) => response.json())
              .filter((responseData) => responseData.status !== 'PENDING')
              .take(1)
              .map((response) => response.status)
              .catch((error) => Observable.throw({message: 'FAILED'}))
              .timeout(5000);
          };

在我的测试中,我想执行pollStatus()函数,并确保getStatus()函数被调用了正确的次数等,但我不能让它调用它一次。测试Observable.interval的最佳方法是什么?如何强制新的间隔发生?

1 个答案:

答案 0 :(得分:0)

要测试Rx代码,您需要传递VirtualTimeScheduler,以便提高测试时间。您可以使用compat包@kwonoj/rxjs-testscheduler-compat,这样您就可以在RxJs5中编写测试,就像在RxJs4中编写测试一样:

import { TestScheduler, next, complete } from '@kwonoj/rxjs-testscheduler-compat';

const scheduler = new TestScheduler();
const results = scheduler.startScheduler(
  () => pollStatus(scheduler),
  { created: 100, subscribed: 200, unsubscribed: 4000 }
);

您需要将调度程序传递给基于时间的运算符,这样他们才能安排他们的工作不是默认调度程序,而是您提供的调度程序:

pollStatus = (scheduler?:Rx.Scheduler): Observable<string> => {
  return Observable.interval(1000, scheduler)
    .mergeMap(() => this.getStatus(); // this makes a http call to a status api
    .map((response) => response.json())
    .filter((responseData) => responseData.status !== 'PENDING')
    .take(1)
    .map((response) => response.status)
    .catch((error) => Observable.throw({message: 'FAILED'}))
    .timeout(5000, scheduler);
};

然后您可以观察到您的代码在测试中的虚拟时间运行,然后您可以开始为this.getStatus()创建模拟,使其慢于5000毫秒,以便timeout()点击等等。