【问题标题】:What is the difference between tick() and flush() in angular testing?角度测试中的 tick() 和 flush() 有什么区别?
【发布时间】:2019-10-23 05:24:43
【问题描述】:

在 Angular 文档中,我看到了这两个函数,tick()flush()。这两个似乎都做类似的事情。从角度文档中,它说:

模拟 fakeAsync 区域中计时器的异步时间流逝。

对于冲洗:

通过排空宏任务队列直到它为空,模拟 fakeAsync 区域中的计时器的异步时间流逝。返回值是已经过去的毫秒数。

谁能给我解释一下区别?

编辑(在 cmets 中回答):

另外,angular documentationtick()是不带参数使用的,该行的注释甚至使用了短语“flush”

it('should display error when TwainService fails', fakeAsync(() => {
  // tell spy to return an error observable
  getQuoteSpy.and.returnValue(
    throwError('TwainService test failure'));

  fixture.detectChanges(); // onInit()
  // sync spy errors immediately after init

  tick(); // flush the component's setTimeout()

  fixture.detectChanges(); // update errorMessage within setTimeout()

  expect(errorMessage()).toMatch(/test failure/, 'should display error');
  expect(quoteEl.textContent).toBe('...', 'should show placeholder');
}));

【问题讨论】:

    标签: angular typescript testing ionic-framework jasmine


    【解决方案1】:

    相对于之前启动的异步操作,它们做了不同的事情。例如;调用 setTimeout(...) 会启动异步操作。

    • tick()时间向前移动。
    • flush()时间移到末尾。

    这些功能的单元测试可以更好地说明这一点。

    打勾

    此单元测试显示,在所有 10 个计时器完成之前,tick 被用于以 steps 的方式将时间向前移动。 Tick 被多次调用。

    https://github.com/angular/angular/blob/master/packages/core/test/fake_async_spec.ts#L205

    
          it('should clear periodic timers', fakeAsync(() => {
               let cycles = 0;
               const id = setInterval(() => { cycles++; }, 10);
    
               tick(10);
               expect(cycles).toEqual(1);
    
               discardPeriodicTasks();
    
               // Tick once to clear out the timer which already started.
               tick(10);
               expect(cycles).toEqual(2);
    
               tick(10);
               // Nothing should change
               expect(cycles).toEqual(2);
             }));
    

    冲洗

    这个单元测试表明所有异步任务在返回时都应该完成,并且返回的值告诉你完成它们需要多长时间。

    https://github.com/angular/angular/blob/master/packages/core/test/fake_async_spec.ts#L273

          it('should flush multiple tasks', fakeAsync(() => {
               let ran = false;
               let ran2 = false;
               setTimeout(() => { ran = true; }, 10);
               setTimeout(() => { ran2 = true; }, 30);
    
               let elapsed = flush();
    
               expect(ran).toEqual(true);
               expect(ran2).toEqual(true);
               expect(elapsed).toEqual(30);
             }));
    

    【讨论】:

    • 这是有道理的,但从angular documentation 来看,使用不带任何参数的tick() 似乎可以有效地进行刷新。
    • @JustinKavalan 是的,我也读过。因此,基本上没有参数意味着tick()all 向前移动。所以它与flush() 相同。不同之处在于tick() 不返回经过的时间。
    • @JustinKavalan 如果这回答了您的问题。请接受它作为答案。
    • 我只是想补充一点,tick()flush() 不相等。我有一个测试,我在单击触发的订阅中监视router.navigate,并使用tick() 在队列中留下一个定期计时器,而flush() 没有。 (有趣的是flush() 在这个测试中总是返回 500 毫秒。)
    • 我认为没有参数的tick() 只是运行即时计时器,例如setTimeout(() => doSomething(), 0)flush() 基本上就是while(testZone.hasPendingTasks) { tick(1); }
    猜你喜欢
    • 2019-04-25
    • 2018-04-01
    • 2020-04-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-24
    • 2011-08-22
    相关资源
    最近更新 更多