如何测试在rxjs 5中使用定时间隔返回可观察量的函数?

时间:2017-03-11 08:18:00

标签: rxjs rxjs5

例如,我有一个这样的函数:

export function timeRange(start: number, end: number): Rx.Observable<number> {
  return Rx.Observable.interval(1000)
  .map(n => n + start)
  .take(end - start + 1)
}

我进行了一次单元测试,运行timeRange(10,100)并对其声明了值。

问题是时间间隔会使我的测试运行时间过长。

如何在不触及功能的情况下缩短时间间隔?

我尝试在调度程序上阅读文档,但我没有得到它。

4 个答案:

答案 0 :(得分:7)

有几点需要注意,但您可以按如下方式测试您的功能:

const Rx = require('rxjs');
const chai = require('chai');

function timeRange(start, end, interval = 1000, scheduler = Rx.Scheduler.async) {
  return Rx.Observable.interval(interval, scheduler)
    .map(n => n + start)
    .take(end - start + 1)
}

let scheduler = new Rx.TestScheduler(chai.assert.deepEqual);
let source = timeRange(2, 8, 50, scheduler);
let values = {'2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8};
scheduler.expectObservable(source).toBe('-----2----3----4----5----6----7----(8|)', values);

scheduler.flush();

注意几点:

  • 该函数现在有四个参数。我们需要使用的时间间隔Scheduler来传递TestScheduler

  • TestScheduler需要获得深度比较对象的方法。它将用于比较Notification个对象的数组。

  • 您无法使用1000,因为允许的最长时间为hardcoded as 750。请注意,这只是虚拟时间且与实时无关,因此我们在此测试中使用的5050ms不同。我们只需要在750时间范围内适应。

  • 然后大理石测试为典型的大理石测试。有关详细信息,请参阅https://github.com/ReactiveX/rxjs/blob/master/doc/writing-marble-tests.md。请注意,我不能使用与默认RxJS运算符相同的全局mocha函数。

  • 我还必须指定值,因为大理石测试默认使用字符串,我需要强制整数以确保深度相等。

您可以通过更改一个大理石值来测试此失败:

let values = {'2': 42, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8};

此外,您可以通过将通知对象打印到控制台来查看通知对象:

let scheduler = new TestScheduler((actual, expected) => {
   console.log('Actual:', actual, '\n\n', 'Expected:', expected);
   chai.assert.deepEqual(actual, expected);
});

使用RxJS 5 mocha助手

目前,RxJS 5并未公开mocha测试助手。我实际上正在我正在进行的另一个项目中使用它(包括生成图表图像)。您可以在此处https://github.com/martinsik/rxjs-extra查看package.json我正在使用的脚本。它运作良好,但设置有点难以理解。它涉及下载RxJS 5存档,复制一些文件并使用couple of files修补它。然后,mocha测试的默认选项设置为mocha.opts,该选项基于RxJS 5中的原始。

答案 1 :(得分:3)

您可以创建TestSchedulerVirtualTimeScheduler,并将其作为可选的第二个参数传递给Observable.Interval。在您的情况下,您只需向timeRange添加一个可选的调度程序参数并传递该值。

这些测试调度程序允许您通过时间&#34;无需等待实际时间过去。

有关更多信息和示例,请参阅Testing your Rx Application

答案 2 :(得分:3)

我最近遇到了同样的问题并发现了marble testing,它让你编写了令人敬畏的视觉测试,使定时的Observable测试非常容易。

大理石测试抽象了时间,测试立即运行(通过使用TestScheduler),但您仍然可以测试复杂的定时过程。这是一个示例测试,可以让您了解语法:

it('should set up an interval', () => {
  const expected = '----------0---------1---------2---------3---------4---------5---------6-----';
  expectObservable(Observable.interval(100, rxTestScheduler)).toBe(expected, [0, 1, 2, 3, 4, 5, 6]);
});

这实际上是来自rxjs5回购的Observable.interval的官方单元测试:https://github.com/ReactiveX/rxjs/blob/master/spec/observables/interval-spec.ts

查看official documentation了解详情。

让它运行是一个挑战,但你基本上只需要来自marble testing example project的两个文件marble-testing.tstest-helper.ts

答案 3 :(得分:0)

这对我很有用:rxjs-testscheduler-compat。来自自述文件:

  

rxjs-testscheduler-compat为Vx版本的RxJS提供了RxJS v4的测试调度程序接口,允许以最小的工作量迁移现有的测试用例,并为某些情况编写新的测试用例。