unit testing - How can I avoid passing the scheduler through my business logic, when writing tests for RXJS observables? -
i finding way make tests pass explicitly pass scheduler functions. illustration, consider function:
function dostuff( stream ){     return stream.delay(100)         .filter( x => x % 2 === 0 )         .map( x => x * 2 )         .flatmaplatest( x=> rx.observable.range( x, x+100) )   and test:
it('example test', () => {     let scheduler = new rx.testscheduler()     let xs = scheduler.createhotobservable(         onnext(210, 1),         onnext(220, 2),         onnext(230, 3)     )      let res = scheduler.startscheduler(         () => dostuff( xs, scheduler ),         {created:0, subscribed:200, disposed:1000})      expect( res.messages ).toequal( [         onnext(321, 4),         onnext(322, 5),         onnext(323, 6)     ] ) })   which gives error:
    expected [  ] equal [ ({ time: 321, value: onnextnotification({ value: 4, kind: 'n' }), comparer: function }), ({ time: 322, value: onnextnotification({ value: 5, kind: 'n' }), comparer: function }), ({ time: 323, value: onnextnotification({ value: 6, kind: 'n' }), comparer: function }) ].   this suggests delay happening in real time instead of simulated time of testscheduler.
if pass scheduler every operator, can make work:
function dostuff( stream, scheduler ){    return stream.delay( 100, scheduler )       .filter( x => x % 2 === 0 )       .map( x => x * 2 )       .flatmaplatest( x => rx.observable.range(x, 3, scheduler ) ) }   but feels me should able set scheduler once , not have have real production code have thread through. expecting that, given original stream created testscheduler , run via same scheduler, automatically wired up.
the rx guidelines suggest consider passing specific scheduler concurrency introducing operators. single-threaded javascript, there no concurrency, time-based operators delay() have similar concern.
this isn't bad first thought, majority of operators not have scheduler argument, , subset of time-based. , highlights why explicitly pass scheduler. in example above, passed through scheduler every operator supported it, results weren't expected - tweaked "expected" result make work:
expect( res.messages ).toequal( [     onnext(321, 4),     onnext(322, 5),     onnext(323, 6) ] )   but really, expecting of timings 320.
for delay(), need inherit scheduler test, range() want default scheduler instead, because schedule events immediately.
my final example code snippet this:
function dostuff( stream, scheduler ){     return stream.delay( 100, scheduler )         .filter( x => x % 2 === 0 )         .map( x => x * 2 )         .flatmaplatest( x => rx.observable.range(x, 3)) }   when creating tests, always want using testscheduler time-based operators. other operators want use defaultscheduler regardless of if test running.
Comments
Post a Comment