使用interval()进行角度测试

时间:2020-06-17 07:04:18

标签: angular angular9 angular-test angular-testing

在我的ngOnInit中,我检查一条路线,做一些事情,然后设置一个interval

ngOnInit(): void {
    this.routeSubscription = this.route.paramMap.subscribe(x => {
         ...
         // Reload the data every 60 seconds
         interval(60_000)
             .pipe(takeUntil(this.cancelInterval$))
             .subscribe(() => this.rows$ = this.orderService.active())
    })
}

当我尝试进行单元测试时,茉莉花会中止,因为异步方法返回的速度不够快。我正在这样做(作为主要组件的子描述,它完成所有常规的TestBed设置):

describe('when showing active orders', () => {
    beforeEach(() => {
        activatedRoute.setParamMap({})
        fixture.detectChanges()
    })

    it('...', async () => {
        await fixture.whenStable()
        ...
    })

由于间隔,它似乎卡住了。我以为我可以在discardPeriodicTasks()方法的末尾给beforeEach打电话,但这没用。

因此,我正在寻找在测试中处理此问题的正确方法,或者在生产代码中寻找一种仅在未通过测​​试运行间隔调用时进行间隔调用的方法。

Angular CLI:9.0.7
节点:14.4.0
角度:9.1.6

2 个答案:

答案 0 :(得分:1)

而不是直接调用RXJS interval(),而是创建一个像这样的简单中间服务:

import { Injectable } from '@angular/core';
import { interval } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class TimerService {

  interval(ms: number) {
      return interval(ms);
  }

}

在组件中注入并使用它:timer.interval(60_000)

现在,在单元测试中模拟interval()的必要行为很简单,例如:

providers: [{ provide: TimerService, useValue: { interval: () => of(1) } }],

答案 1 :(得分:0)

您可以使用fakeAsync并勾选以模拟异步行为

it('...', fakeAsync () => { tick(60000); doTestStuff(); })

相关问题