【问题标题】:Using marble testing for a function that returns an Observable对返回 Observable 的函数使用弹珠测试
【发布时间】:2018-03-12 19:42:00
【问题描述】:

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

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

我想为此编写单元测试,我正在尝试使用 rxjs-marbles 并遵循 RxJS 的 writing marble tests 说明。

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

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

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

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

但是我总是得到Expected &lt;blank&gt; to equal ...,即源是空白的。我认为这是因为源 Observable 不热,但即使我这样做 source.subscribe() 在断言之前我得到了同样的错误。使用 m.cold 作为测试 observable 无关紧要。

如何使用 RxJS 弹珠测试返回 observable 的函数?

【问题讨论】:

  • 我认为(或至少一个)问题是interval 默认使用异步调度程序。您需要将 TestScheduler 传递给它,这意味着您需要扩展您的打字机以采用(可选)调度程序参数,它将转发到frominterval。对于from,它不需要让它工作(我相信),但既然你无论如何都需要添加它,不妨把它做对:-)
  • 也就是说,对预期状态使用冷可观察对象应该完全没问题。

标签: typescript rxjs


【解决方案1】:

您的typewriter 函数使用interval observable 创建者,但只传递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);

调用绑定猴子修补所有调度程序以将调用转发到测试的TestScheduler

【讨论】:

  • 谢谢!我应该更彻底地阅读文档。也感谢图书馆。
  • 不用担心。自述文件随着时间的推移而增长,现在有点笨拙。这些天我会重新组织它。
  • 哈!在我的 Twitter 提要中查看what just popped up
猜你喜欢
  • 2020-01-19
  • 2020-01-09
  • 2019-02-04
  • 2019-12-15
  • 2019-05-18
  • 2021-09-03
  • 1970-01-01
  • 2022-01-20
  • 2021-09-14
相关资源
最近更新 更多