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

六月ゝ 毕业季﹏ 提交于 2019-12-07 09:11:47

问题


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!


回答1:


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:

  • https://github.com/ReactiveX/rxjs/blob/master/doc/marble-testing.md

  • https://github.com/ReactiveX/rxjs/blob/master/doc/internal-marble-tests.md




回答2:


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



来源:https://stackoverflow.com/questions/50406951/how-to-test-observables-which-emit-grouped-events-with-rxjs-marbles

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!