Angular 组件和服务是不是应该始终避免使用 setInterval(或 rxjs 计时器)?
Posted
技术标签:
【中文标题】Angular 组件和服务是不是应该始终避免使用 setInterval(或 rxjs 计时器)?【英文标题】:Should Angular components and services always avoid using setInterval (or rxjs timer)?Angular 组件和服务是否应该始终避免使用 setInterval(或 rxjs 计时器)? 【发布时间】:2021-01-28 16:44:24 【问题描述】:我有一些组件和服务在后台定期执行操作——刷新数据、更新显示的日期/时间等。我最初使用setInterval
编写了这些功能。现在,我要回去添加单元测试。我花了方式太长时间试图弄清楚为什么我的测试不工作 - 事实证明,如果被测组件(或其任何依赖项!)创建间隔,fixture.whenStable()
将永远无法解决.我尝试从 setInterval
切换到 rxjs interval
/ timer
,但它们有同样的问题。
在this older question 上给出的建议是将实际的setInterval
调用放在专用的“间隔服务”中,然后在编写测试时使用tick
-able 来模拟服务。我不喜欢改变我的(工作!)代码以适应测试的想法,如果我能提供帮助的话,但我认为我真的需要whenStable
才能工作。除其他外,Angular Material TestbedHarnessEnvironment
在引擎盖下使用它,据我所知,任何包含间隔的组件都不能使用 Material 线束。
我的问题是:截至 2020 年底,我还有更好的选择吗?有没有办法为包含实际间隔的组件或服务编写waitForAsync
风格的测试?或者有没有更好的模式可以用于我的组件设计,也许是一些与现有 Zone.js 测试补丁集成的间隔替换?
【问题讨论】:
【参考方案1】:我有一个类似(不完全相同)的问题,我解决了如下问题:在测试代码中,在调用 fixture.detectChanges()
之后,我停止了我的计时器(通过取消订阅)。测试代码中唯一的变化是使用公共函数公开取消订阅代码,例如:
stopTimers()
this.intervalSubs?.unsubscribe();
然后在你的测试代码中:
component = fixture.componentInstance;
fixture.detectChanges();
component.stopTimers();
【讨论】:
我忘记了这个问题。我从来没有想出更好的解决方案。在某些情况下,我可以通过模拟对使用计时器的服务的依赖来使用whenStable
(当然模拟不需要它们),而在其他情况下,我只是避免使用whenStable
并手动依赖@987654326 @-ing,在测试结束时带有discardPeriodicTasks
。我从来没有采用TestbedHarnessEnvironment
...以上是关于Angular 组件和服务是不是应该始终避免使用 setInterval(或 rxjs 计时器)?的主要内容,如果未能解决你的问题,请参考以下文章
我应该在注入的 Angular 服务上使用只读而不是公开它们吗?