我有一个函数,它接受一个数组并返回一个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弹珠测试返回可观察对象的函数?
答案 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
的调用。