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