首页 > 解决方案 > 尽管在 fakeAsync 中刷新,但计时器仍在队列中

问题描述

我有这个测试会导致臭名昭著的“1个计时器仍在队列中”错误:

import {
discardPeriodicTasks,
  fakeAsync,
  flush,
  flushMicrotasks,
  tick
} from "@angular/core/testing";

describe("Sleep", () => {
  const sleep = (ms: number) => new Promise(resolve => setTimeout(resolve, ms));

  it("should sleep async", async () => {
    let slept = false;
    await sleep(0).then(() => (slept = true));
    expect(slept).toBeTruthy();
  });

  it("should sleep fakeAsync", fakeAsync(async () => {
    let slept = false;
    await sleep(0).then(() => (slept = true));
    flush();
    flushMicrotasks();
    discardPeriodicTasks();
    tick(1000);
    expect(slept).toBeTruthy();
  }));
});

包括此答案中的提示在内的任何刷新或滴答声都不会摆脱计时器。我还可以做些什么?没有的变体fakeAsync()工作正常。

Stackblitz:https ://stackblitz.com/edit/test-jasmine-karma-fakeasync-timer?file=app/test.ts

标签: karma-jasmineangular-test

解决方案


无论出于何种原因,如果您将其转换sleep(0) Promise为一个,它就会起作用Observable

it("should sleep fakeAsync", fakeAsync(async () => {
  let slept = false;
  //await sleep(0).then(() => (slept = true));
  from(sleep(0)).subscribe(() => (slept = true));
  expect(slept).toBeFalsy();
  tick(0);
  expect(slept).toBeTruthy();
}));

我从 Rxjs 遇到了一个类似的问题debounceTime,没有数量flush()flushMicroTasks()或者discardPeriodicTasks()会释放去抖动。tick()然而,在我的情况下,我能够通过在我的期望完成以允许完成后以足够大的时间值调用来解决我的问题debounceTime


推荐阅读