gpt4 book ai didi

javascript - Jest 单元测试 - 如何在 setTimeout 重复函数中调用异步函数

转载 作者:行者123 更新时间:2023-12-01 16:18:43 26 4
gpt4 key购买 nike

更新:可以肯定地说这基本上是 Jest: Timer and Promise don't work well. (setTimeout and async function) 的副本


我有一个函数在执行异步函数后会自行重复。我想验证 jest.advanceTimersOnTime(5000) 继续产生 expect(doAsyncStuff).toHaveBeenCalledTimes(X);

我观察到我们可以调用 repeat 函数,但在请求 jest 提前计时器时它不会“通过”。当您删除它前面的异步函数时,它确实有效。所以听起来我必须让 doAsyncStuff 在这里“调用”或解决一些悬而未决的 promise ?

函数

function repeatMe() {
setTimeout(() => {
doAsyncStuff.then((response) => {
if (response) {
console.log("I get here!");
repeatMe();
}
})
}, 5000);
}

测试

jest.useFakeTimers();

let doAsyncStuff = jest.spyOn(updater, 'doAsyncStuff');
doAsyncStuff.mockResolvedValue(true);

repeatMe();

jest.advanceTimersByTime(5000);
expect(doAsyncStuff).toHaveBeenCalledTimes(1);

jest.advanceTimersByTime(5000);
expect(doAsyncStuff).toHaveBeenCalledTimes(2); // Failed?

最佳答案

So it sounds like I have to...resolve some pending promise here?

是的,完全正确。


简短的回答是 Promise 回调在 PromiseJobs 中排队。通过链接到 doAsyncStuff 返回的 Promisethen,以及编写测试的方式,那个回调永远没有机会运行直到测试已经结束

要修复它,请在测试期间给 Promise 回调一个运行的机会:

更新器.js

export const doAsyncStuff = async () => { };

代码.js

import { doAsyncStuff } from './updater';

export function repeatMe() {
setTimeout(() => {
doAsyncStuff().then((response) => {
if (response) {
console.log("I get here!");
repeatMe();
}
})
}, 5000);
}

代码.test.js

import * as updater from './updater';
import { repeatMe } from './code';

test('repeatMe', async () => {
jest.useFakeTimers();

let doAsyncStuff = jest.spyOn(updater, 'doAsyncStuff');
doAsyncStuff.mockResolvedValue(true);

repeatMe();

jest.advanceTimersByTime(5000);
expect(doAsyncStuff).toHaveBeenCalledTimes(1); // Success!

await Promise.resolve(); // let callbacks in PromiseJobs run

jest.advanceTimersByTime(5000);
expect(doAsyncStuff).toHaveBeenCalledTimes(2); // Success!

await Promise.resolve(); // let callbacks in PromiseJobs run

jest.advanceTimersByTime(5000);
expect(doAsyncStuff).toHaveBeenCalledTimes(3); // Success!

// ... and so on ...
});

可以在 my answer here 中找到关于究竟发生了什么以及为什么会发生的完整细节。

关于javascript - Jest 单元测试 - 如何在 setTimeout 重复函数中调用异步函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55302069/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com