没有TestScheduler可以对RxJS函数进行单元测试吗?

lar*_*ter 5 unit-testing observable rxjs sinon

tl; dr是否可以在不重写代码的情况下对其进行单元测试?

http://jsbin.com/jezosegopo/edit?js,控制台

const keyUpObserver = ($input, fetchResults) => {
    const source = Rx.Observable.fromEvent($input, 'keyup')
        .map(e => e.target.value)
        .filter(text => text.length > 2)
        .debounce(300)
        .distinctUntilChanged();

    return source.flatMapLatest(text => Rx.Observable.fromPromise(fetchResults(text)));
};
Run Code Online (Sandbox Code Playgroud)

keyUpObserver上面的代码中的代码很大程度上基于RxJS自动完成示例,并使用了反跳来防止锤打服务器。

我正在尝试对该功能进行单元测试,但是Sinon的useFakeTimers似乎无法正常工作。

const clock = sinon.useFakeTimers();

const $input = $('<input>');
const fetchResults = (text) => new Promise(resolve => resolve(text + ' done!'));

keyUpObserver($input, fetchResults).subscribe(text => console.log(text));

$input.val('some text').trigger('keyup');

clock.tick(500);

// Enough time should have elapsed to make this a new event
$input.val('some more text').trigger('keyup');
Run Code Online (Sandbox Code Playgroud)

我猜这也不是与sinon相关的,而是RxJS使用了一些内部时钟,这些时钟必须不受外部伪时钟的影响。

鉴于此,是否有必要对我的keyUpObserver代码进行单元测试,而无需重写它也可以使用调度程序(生产中的默认设置,单元测试中的测试)?


小智 1

...接近答案:似乎 RxJs 正在使用setTimeoutSinon 应该能够覆盖的默认/全局实现。至少这是我在阅读它使用的defiultscheduler's代码时所说的,如果您不传递(如上所述)自定义调度程序。

尽管如此,我对这个意图还是有点困惑。从这个小叉子中,我预计只有第三个触发器才能真正触发它所做的事情,或者我应该越界吗?

  • 嗨,两位,非常感谢您的回复。tdeekens:我可能是错的,但似乎它在文件加载后就缓存这些方法,所以当我尝试用 sinon 来消除时钟时,已经太晚了。至于意图,如果您将最后一个 Clock.tick 更改为 400,这应该足以克服去抖并发送单独的事件......但事实并非如此。paulpdaniels:没有什么大的原因让我无法通过调度程序,只是感觉我必须人为地重写我的代码以允许单元测试。 (2认同)