Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/406.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/351.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript “开玩笑”;在5000毫秒超时时间内未调用异步回调;用猴子补丁的'test'和useFakeTimers_Javascript_Asynchronous_Jestjs - Fatal编程技术网

Javascript “开玩笑”;在5000毫秒超时时间内未调用异步回调;用猴子补丁的'test'和useFakeTimers

Javascript “开玩笑”;在5000毫秒超时时间内未调用异步回调;用猴子补丁的'test'和useFakeTimers,javascript,asynchronous,jestjs,Javascript,Asynchronous,Jestjs,这个设置非常具体,但我在网上找不到任何类似的资源,所以我在这里发布,以防对任何人有所帮助 关于Jest有很多问题,并且没有调用异步回调,但我没有发现任何问题的根源在于使用Jest.useFakeTimers()。当使用假计时器时,我的函数应该不会花时间执行,但由于某些原因,Jest挂起了 我使用的是Jest 26,所以我手动指定使用modern计时器 这是演示该问题的完整代码段 jest.useFakeTimers('modern')) 让setTimeoutSpy=jest.spyOn(全局

这个设置非常具体,但我在网上找不到任何类似的资源,所以我在这里发布,以防对任何人有所帮助


关于Jest有很多问题,并且没有调用
异步回调
,但我没有发现任何问题的根源在于使用
Jest.useFakeTimers()
。当使用假计时器时,我的函数应该不会花时间执行,但由于某些原因,Jest挂起了

我使用的是Jest 26,所以我手动指定使用
modern
计时器

这是演示该问题的完整代码段

jest.useFakeTimers('modern'))
让setTimeoutSpy=jest.spyOn(全局“setTimeout”)
异步函数可重试(
fn,
maxRetries=5,
当前尝试=0
) {
试一试{
返回等待fn()
}捕获(e){
如果(当前尝试<最大重试次数){
设置超时(
()=>retryThrowable(fn,最大重试次数,当前尝试次数+1),
1*数学功率(1,当前尝试)
)
}
掷e
}
}
描述('retryThrowable',()=>{
const fnErr=jest.fn(异步()=>{throw new Error('err')})
它('retries`maxRetries`如果结果为错误,则重试次数,'async()=>{
开玩笑
常量maxRetries=5
wait expect(retryThrowable(()=>fnErr(),maxRetries)).rejects.toThrow('err'))
for(let_uu)在数组中(maxRetries.fill(0)){
jest.runAllTimers()
等待承诺。解决()https://stackoverflow.com/a/52196951/3991555
}
expect(setTimeoutSpy).toHaveBeenCalledTimes(maxRetries)
})
})
完整的错误消息是

Timeout - Async callback was not invoked within the 5000 ms timeout specified by jest.setTimeout.Error: Timeout - Async callback was not invoked within the 5000 ms timeout specified by jest.setTimeout.

      at mapper (../../node_modules/jest-jasmine2/build/queueRunner.js:27:45)
任何想法都将不胜感激


编辑1:我尝试了
--detectOpenHandles
,但没有提供新信息



编辑2:我刚刚在一个新项目中尝试了上面的代码片段,并意识到它通过得很好。所以这个问题一定在我的笑话配置中的其他地方。当我确定根本原因时,我将回答我自己的问题。

我的问题最终出现在我的jest配置中

我们直接对内存中的DB执行测试,为了保持测试干净,我们将每个测试包装在一个DB事务中。Jest不像其他许多测试运行程序那样提供原生的
aroundEach
hook,因此我们通过对全局
test
it
函数进行猴子补丁来实现这一点,这样我们就可以在事务内部执行测试回调。不确定这是否重要,但明确地说,我们正在使用Sequelize作为我们的ORM和事务

我正在执行的测试(如上所示)递归地调用了
setTimeout
,函数抛出了一个错误/拒绝了一个承诺。Sequelize事务显然不喜欢未经处理的拒绝,这导致测试挂起。我始终无法找到考试悬而未决的根本原因;事务已成功回滚,所有测试预期都已运行,但由于某些原因,测试从未退出

解决方案#1(不太好) 我的第一个解决方案并不漂亮,但它是务实的。我只是用一个变体扩展了Jest
test
函数,该变体不使用monkey-patched
test

//jest.setup.ts
声明名称空间笑话{
接口{
noDb:(名称:string,fn?:ProvidesCallback,timeout?:number)=>void
}
}
it.noDb=it
//jest.config.js
module.exports={
// ...
SetupFileAfterEnv:[
“./jest.setup.ts”//