【问题标题】:Run background task inside Jest在 Jest 中运行后台任务
【发布时间】:2021-07-02 03:02:07
【问题描述】:

我正在用 Jest 编写一个自动测试框架。为此,我需要在一定的时间间隔内运行一些后台任务。总之,这就像轮询。我们举一个伪代码的例子。

test('Some potato poteto test', () => {
    jest.setTimeout(12000000); // 20 min

    const intervalPeriod = 5 * 60 * 1000; // 5 min

    let retry = 0;

    const intervalId = setInterval(() => {
      console.log("I am doing my 5 minutes check");
      
      // my custom logic goes here

      retry++;
  
      if(retry === MAX_RETRY) { // this will be always hit
        clearInterval(intervalId)
      }
    }, intervalPeriod);
});

因此,每 5 分钟,我将进行一次网络调用,执行一些我的自定义逻辑。现在,问题是在运行它时,测试完成但jest 无法终止。

我的意思是“测试完成”,测试套件运行了,但 setInterval 中的代码没有立即执行。

我的问题是,发生这种情况是因为setInterval 没有立即在事件循环中运行并且jest 没有配置为运行setInterval

请注意,我不想模拟 setInterval,也不想使用任何假计时器。

那么,有没有可能用Jest来实现呢?

我也尝试了与 cron 库的相同的事情,但它是同样的问题。 Jest 不执行代码并完成执行然后停止,因为那些 setInterval/cron 仍在后台运行。

有没有办法在 Jest 中运行这些任务?我的意思是有没有办法运行这些作业并在它们完成后终止 Jest?

【问题讨论】:

  • useFakeTimers 是要走的路……但如果你真的不想……有标志--maxWorkers,它根据你机器的核心跨越工人……仅此测试会消耗整个核心 5 分钟...所以...也许您可以将此测试作为单独的测试? (仅在您执行类似 test:thatonethattakes5min 时运行)

标签: node.js typescript jestjs


【解决方案1】:

这是有意的,Jest 执行所有测试指令并退出测试。

为了开玩笑等待计算,您需要使用 Promises 及其异步模式。

Jest 异步模式的文档:https://jestjs.io/docs/asynchronous

在此处了解有关 Promise 的更多信息:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise

这里还有 async/await 语法:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function

这是一种幼稚的做法:

const MAX_RETRY = 3;
const INTERVAL_PERIOD = 5 * 60 * 1000; // 5 min
const SAFETY_TIME = INTERVAL_PERIOD;
const TEST_TIMEOUT = (1 + MAX_RETRY) * INTERVAL_PERIOD + SAFETY_TIME; 

test('Some potato poteto test', async () => {
    let retry = 0;
    let success = false;
    function yourLogicFunction(): boolean {
        const resultOfYourLogicFunction = retry === MAX_RETRY; // because retry is used in this condition I store the result before changing it
        console.log(`this is my attempt number ${retry}`);
        retry++;
        return resultOfYourLogicFunction;
    }
    function mockRequest(resolve: (value: unknown) => void): void {
        setTimeout(() => resolve(yourLogicFunction()), INTERVAL_PERIOD);
    }
    while (!success && retry <= MAX_RETRY) {
        success = await new Promise(mockRequest) as boolean;
    }
}, TEST_TIMEOUT);

test的第三个参数是超时时间。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-09-05
    • 2015-05-05
    • 2023-03-05
    • 2020-10-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多