Jest 单元测试:setTimeout 在异步测试中未触发

问题描述 投票:0回答:4

我试图了解异步测试在 Jest 中的工作原理。

我想做的与 Jest 文档中的示例类似。这很好用..

function doAsync(c) {
  c(true)
}

test('doAsync calls both callbacks', () => {

  expect.assertions(2);

  function callback1(data) {
    expect(data).toBeTruthy();
  }

  function callback2(data) {
    expect(data).toBeTruthy();
  }

  doAsync(callback1);
  doAsync(callback2);
});

但是我想延迟回调调用,所以我尝试了这个....

 function doAsync(c) {
    setTimeout(() => {
      console.log('timeout fired')
      c(true)
    }, 1000)
  }

但测试失败并显示消息

Expected two assertions to be called but received zero assertion calls.

日志消息“超时已触发”不会出现在控制台中。

请有人能解释一下为什么失败吗?

javascript jestjs
4个回答
39
投票

您需要使用jest的计时器模拟https://jestjs.io/docs/en/timer-mocks

首先告诉 jest 使用模拟计时器,然后在测试中运行计时器。

它看起来像:

function doAsync(c) {
  setTimeout(() => {
      c(true)
    }, 1000)
}

jest.useFakeTimers()

test('doAsync calls both callbacks', () => {

  expect.assertions(2);

  function callback1(data) {
    expect(data).toBeTruthy();
  }

  function callback2(data) {
    expect(data).toBeTruthy();
  }

  doAsync(callback1);
  doAsync(callback2);

  jest.runAllTimers(); // or jest.advanceTimersByTime(1000)
});

6
投票

使用

jest.runAllTimers();
可能会导致以下错误:

跑了100000个计时器,还有更多!假设我们已经击中了 无限递归和救助...

在浏览完JEST计时器模拟文档之后,我发现

setTimeout
进入文档中提到的无限递归。建议使用
jest.runOnlyPendingTimers()
,这样可以解决无限递归错误。

仅快进并耗尽当前待处理的计时器 (但不是在此过程中创建的任何新计时器)

jest.runOnlyPendingTimers();


0
投票

就我而言,它仅在我使用

node:timers/promises
时才有效。示例:

代码不起作用:

const sleep = (index: number) => {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve({});
    }, index * 500);
  });
};

代码工作:

const sleep = (index: number) => {
  return setTimeout(index * 500);
};

-1
投票

在测试用例中使用以下代码作为 setTime out。

it('saveSubscription', () => {
  function doAsync(c) {
    setTimeout(() => {
      component.addSubscription();
      expect(component.subscription.freq).toEqual('immediate');
      component.saveSubscription();
      expect(component.subscription.name).toBe('Untitled 1');
    }, 30000);
  }
});
© www.soinside.com 2019 - 2024. All rights reserved.