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

kho*_*ter 9 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)
}
Run Code Online (Sandbox Code Playgroud)

我进行了一次单元测试,运行timeRange(10,100)并对其进行断言.

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

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

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

mar*_*tin 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();
Run Code Online (Sandbox Code Playgroud)

需要注意几点:

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

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

  • 您无法使用,1000因为允许的最大时间硬编码为750.注意,这只是虚拟时间而与实时无关所以50我们在这个测试中使用的不一样50ms.我们只需要适应那段750时间.

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

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

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

let values = {'2': 42, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8};
Run Code Online (Sandbox Code Playgroud)

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

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

使用RxJS 5 mocha助手

此时RxJS 5不会暴露mocha测试助手.我实际上正在我正在进行的另一个项目中使用它(包括生成图表图像).您可以在这里查看https://github.com/martinsik/rxjs-extrapackage.json我正在使用的脚本中.它运作良好,但设置有点难以理解.它涉及到下载RxJS 5归档,复制一些文件,并用它修补两个文件.然后mocha使用mocha.opts基于RxJS 5的原始设置来设置测试的默认选项.