如何使用具有承诺和延迟的TestScheduler?

时间:2015-09-16 07:48:59

标签: javascript asynchronous jasmine rxjs

我试图让Jasmine,Promises和Rx.TestScheduler一起玩得很好,但是我遇到了一个我似乎无法解决的障碍。

我想要实现的是使用RxJs和Jasmine测试延迟的承诺。

我在这个JsFiddle中创建了一个问题的最小复制品:https://jsfiddle.net/t9gsymu2/2/

这是该小提琴的完整javascript代码:

'use strict';

// fail if a test takes longer than 1 second
jasmine.DEFAULT_TIMEOUT_INTERVAL = 1000;

describe('TestScheduler', function () {
    it('should work when combining the testscheduler and delay', function (done) {
        var scheduler = new Rx.TestScheduler();
        var people = Rx.Observable.just({
            name: 'Jeff'
        });
        var peopleWithTheirAge = people.flatMap(function (person) {
            return Rx.Observable.just({
                name: 'Jeff',
                age: 25
            });
        });
        var delayedPeopleWithTheirAge = peopleWithTheirAge.delay(2000, scheduler);
        delayedPeopleWithTheirAge.subscribe(function (person) {
            expect(person).toEqual({
                name: 'Jeff',
                age: 25
            });
            done();
        });
        scheduler.start();
    });

    it('should work when combining the testscheduler, delay AND a promise', function (done) {
        var scheduler = new Rx.TestScheduler();
        var people = Rx.Observable.just({
            name: 'Jeff'
        });
        var peopleWithTheirAge = people.flatMap(function (person) {
            return Promise.resolve({
                name: 'Jeff',
                age: 25
            });
        });
        var delayedPeopleWithTheirAge = peopleWithTheirAge.delay(2000, scheduler);
        delayedPeopleWithTheirAge.subscribe(function (person) {
            expect(person).toEqual({
                name: 'Jeff',
                age: 25
            });
            done();
        });
        scheduler.start();
    });
});

两个测试都与T相同,唯一的区别是第一个测试使用Rx.Observable.just而第二个测试使用Promise.resolve。 (我可以使用Rx.Observable.fromPromise来确保实际创建了一个Observable,但是1.我已经尝试过了2. https://github.com/Reactive-Extensions/RxJS/blob/master/doc/gettingstarted/promises.md的文档明确指出flatMap支持Promise对象)

第一次测试立即成功。 Observable使用Rx.TestScheduler延迟2秒,可以模拟时间。 scheduler.start()方法立即执行任何计划任务,而不是等待2秒。 Jasmine使用" done"支持异步测试。测试中的参数,实际上只是在您考虑完成测试时需要调用的函数。

但是,第二次测试失败了。我假设这与Promises异步有关,这导致TestScheduler无法接收那些回调中发生的任何事情。

非常感谢任何有关此事的帮助!

1 个答案:

答案 0 :(得分:1)

我最近大火了,这是我第二次在SO上发布问题后不久找到答案。

无论如何,解决方案是使用内置于RxJs库的MockPromise。

因此,不要使用Promise.resolve(true),而是使用scheduler.createResolvedPromise(100, true)

这是工作小提琴:https://jsfiddle.net/t9gsymu2/4/

完整代码:

'use strict';

// fail if a test takes longer than 1 second
jasmine.DEFAULT_TIMEOUT_INTERVAL = 1000;

describe('TestScheduler', function () {
    it('should work when combining the testscheduler and delay', function (done) {
        var scheduler = new Rx.TestScheduler();
        var people = Rx.Observable.just({
            name: 'Jeff'
        });
        var peopleWithTheirAge = people.flatMap(function (person) {
            return Rx.Observable.just({
                name: 'Jeff',
                age: 25
            });
        });
        var delayedPeopleWithTheirAge = peopleWithTheirAge.delay(2000, scheduler);
        delayedPeopleWithTheirAge.subscribe(function (person) {
            expect(person).toEqual({
                name: 'Jeff',
                age: 25
            });
            done();
        });
        scheduler.start();
    });

    it('should work when combining the testscheduler, delay AND a promise', function (done) {
        var scheduler = new Rx.TestScheduler();
        var people = Rx.Observable.just({
            name: 'Jeff'
        });
        var peopleWithTheirAge = people.flatMap(function (person) {
            return scheduler.createResolvedPromise(100, {
                name: 'Jeff',
                age: 25
            });
        });
        var delayedPeopleWithTheirAge = peopleWithTheirAge.delay(2000, scheduler);
        delayedPeopleWithTheirAge.subscribe(function (person) {
            expect(person).toEqual({
                name: 'Jeff',
                age: 25
            });
            done();
        });
        scheduler.start();
    });
});