对返回Observable的函数使用大理石测试

时间:2018-03-12 19:42:00

标签: typescript rxjs

我有一个函数,它接受一个数组并返回一个Observable(基本上在每次延迟后从给定数组中发出每个值):

export const typewriter = <T>(str: T[], delay = 20) =>
  zip(interval(delay), from(str)).pipe(map(([, str]) => str));

我想为此编写单元测试,我正在尝试使用rxjs-marbles并按照RxJS的writing marble tests说明进行操作。

所有示例似乎都需要热源可观察和冷观察,以便您比较预期值。在这种情况下,我有一个返回冷可观察的函数。我试过这样写:

const expected = m.hot('-^-a-b-(c|)');

const source = typewriter(['a', 'b', 'c']);

m.expect(source).toBeObservable(expected);

但是我总是得到Expected <blank> to equal ...,即来源是空白的。我认为这是因为源Observable不热,但即使我这样做 在断言之前source.subscribe()我得到了同样的错误。使用m.cold进行测试可观察无关紧要。

如何使用RxJS弹珠测试返回可观察对象的函数?

1 个答案:

答案 0 :(得分:5)

您的typewriter函数使用interval可观察的创建者,但仅传递delay。这意味着它将使用创建者的默认调度程序。

要与大理石测试一起使用,需要使用TestScheduler - 可通过m.scheduler获取。

将测试调度程序传递给深度嵌套的observable可能会很痛苦。 rxjs-marbles包含bind方法 - 请参阅the docs - 以简化此操作:

m.bind();
const expected = m.hot('-^-a-b-(c|)');
const source = typewriter(['a', 'b', 'c']);
m.expect(source).toBeObservable(expected);

调用bind monkey会修补所有调度程序,以转发对测试TestScheduler的调用。