2015-09-16 42 views
3

我试图让茉莉花,承诺和Rx.TestScheduler一起玩,但我遇到了一个障碍,我似乎无法解决。如何使用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,以确保可观察到的实际创建,但1。我已经试过了,并2. https://github.com/Reactive-Extensions/RxJS/blob/master/doc/gettingstarted/promises.md的文件明确指出flatMap支持无极对象)

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

但是,第二次测试失败。我假设这与Promises是异步的有关,这会导致TestScheduler不能处理这些回调中发生的任何事情。

任何有关此事的帮助将不胜感激!

回答

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(); 
    }); 
}); 
+1

这是正确的。另一方面,如果你将使用'TestScheduler',你实际上并不需要'完成'。 '开始'返回所有的值已被处理。此外,通常使用“MockObserver”更容易,而不是在订阅模块中显式地进行比较。 – paulpdaniels

+0

再次感谢您的额外信息!我从你那里学到很多东西。你是RxJs的贡献者吗? – Moeri

+0

没问题!是的,我是贡献者之一。 – paulpdaniels