例如,我有一个这样的函数:
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)并对其声明了值。
问题是时间间隔会使我的测试运行时间过长。
如何在不触及功能的情况下缩短时间间隔?
我尝试在调度程序上阅读文档,但我没有得到它。
答案 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。请注意,这只是虚拟时间且与实时无关,因此我们在此测试中使用的50
与50ms
不同。我们只需要在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)
您可以创建TestScheduler
或VirtualTimeScheduler
,并将其作为可选的第二个参数传递给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.ts
和test-helper.ts
。
答案 3 :(得分:0)
这对我很有用:rxjs-testscheduler-compat。来自自述文件:
rxjs-testscheduler-compat为Vx版本的RxJS提供了RxJS v4的测试调度程序接口,允许以最小的工作量迁移现有的测试用例,并为某些情况编写新的测试用例。