简体   繁体   中英

How to test observables which emit grouped events with rxjs marbles?

According to rxjs marbles documentation the current behaviour for the sync groupings is the following:

'(ab)-(cd)': on frame 0, emits a and b then on frame 50, emits c and d

From the docs:

While it can be unintuitive at first, after all the values have synchronously emitted time will progress a number of frames equal to the number of ASCII characters in the group, including the parentheses

Ok, but how do I test an observable like this (using marbles or any other technique):

const observable$ = of(1, 2).concat(of(3, 4).delay(20));

Are there any workarounds?

There is a similar question on Stack Overflow but there is no answer on 'How to actually work around it and test this kind of observable'.

Thanks!

I don't know what version of RxJS you're using because you're mixing prototypical and pipable operators but it looks like RxJS 5.5.

In RxJS 5.X it's a bit clumsy. You could rewrite your test like this:

import { of } from 'rxjs/observable/of';
import { TestScheduler } from 'rxjs/testing/TestScheduler';
import { assert } from 'chai';
import 'rxjs/add/operator/concat';
import 'rxjs/add/operator/delay';

const scheduler = new TestScheduler((actual, expected) => {
  console.log(actual, expected);
  return assert.deepEqual(actual, expected);
});

const observable$ = of('a', 'b').concat(of('c', 'd').delay(50, scheduler));

scheduler
  .expectObservable(observable$)
  .toBe('(ab)-(cd|)');

scheduler.flush();

See live demo (open console): https://stackblitz.com/edit/rxjs5-marble-test?file=index.ts

You know this test passes because it doesn't throw any error. Try changing any of the delays or values of next emissions and it'll throw an error.

Also have a look at this answer: How do I test a function that returns an observable using timed intervals in rxjs 5?

However, I'd strongly recommend upgrading to RxJS 6 because it makes everything much easier with cold and hot "creation" functions where you could just use const observable$ = cold('(ab)-(cd|)') to create the same sequence as you're doing with of(...).concat(...) .

Testing in RxJS 6:

For my project I migrated to rx-sanbox where sync grouping works correct and it solved my problem.

So, in rx-sandbox this is correct: '(ab)-(cd)': on frame 0, emits a and b then on frame 20, emits c and d

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM