javascript - 在 setTimeout 之前和之后使用异步函数调用开玩笑
问题描述
我有一个主函数,它调用两个异步函数,中间有睡眠函数。这是一个基本示例:
index.js
const func1 = async() => {
setTimeout(()=>{console.log('func 1...')}, 1000);
}
const func2 = async() => {
setTimeout(()=>{console.log('func 2...')}, 1000);
}
const sleep = ms => {
console.log(`Sleeping for ${ms/1000} seconds`);
return new Promise(resolve => {
setTimeout(resolve, ms);
})
}
const main = async() => {
try {
await func1();
// Sleeping for a long long time
console.log('Before Sleep');
await sleep(2000000);
console.log('After Sleep')
await func2();
return 'success';
} catch(err) {
console.log(err);
return 'error'
}
}
这是我的测试代码:
index.test.js
const index = require('./index');
jest.useFakeTimers();
describe('Testing index.js...', () => {
test('Should return success', async() => {
const promise = index();
jest.advanceTimersByTime(2000000);
promise.then(response => {
expect(response).toBe('success');
})
});
})
测试通过,但控制台显示以下内容:
func 1...
Before Sleep
Sleeping for 2000 seconds
我尝试了同样的方法,但是 func1() 和 func2() 是同步函数:
const func1 = () => {
console.log('func 1...');
}
const func2 = () => {
console.log('func 2...');
}
const sleep = ms => {
// Sleeping for a long time
console.log(`Sleeping for ${ms/1000} seconds`);
return new Promise(resolve => {
setTimeout(resolve, ms);
})
}
const main = async() => {
try {
func1();
// Sleeping for a long long time
console.log('Before Sleep');
await sleep(2000000);
console.log('After Sleep')
func2();
return 'success';
} catch(err) {
console.log(err);
return 'error'
}
}
在这种情况下,测试通过并且日志也符合预期:
func 1...
Before Sleep
Sleeping for 2000 seconds
After Sleep
func 2...
在相同的同步代码中,如果我使 func1 异步(保持 func2 同步),问题会再次出现。如果 func1 是同步的,而 func2 是异步的,那么一切都会按预期工作。
我也尝试过使用 jest.runAllTimers() 和 jest.runOnlyPendingTimers()。我也尝试在测试文件中使用 async-await ,但是(可以理解)给出了超时错误:
index.test.js使用异步等待
const index = require('./index');
jest.useFakeTimers();
describe('Testing index.js...', () => {
test('Should return success', async() => {
const promise = index();
jest.advanceTimersByTime(3000000);
const response = await promise;
expect(response).toBe('success');
});
})
控制台:
func 1...
Before Sleep
Sleeping for 2000 seconds
错误:
Timeout - Async callback was not invoked within the 5000ms timeout specified by jest.setTimeout.Timeout
我怎样才能使这项工作?我开玩笑地尝试了很多 Github 问题的解决方案,还有很多关于堆栈溢出的问题,但似乎没有一个解决方案有效。
我正在使用 jest 25.5.4
编辑:我还尝试将 jest.advanceTimersBytTime() 中的值增加到一天。并且还尝试在描述异步中创建函数。
解决方案
我最近遇到了类似的问题,对我有用的是从异步调用中推进计时器。似乎 jest 不支持在承诺中设置计时器(请参阅https://github.com/facebook/jest/pull/5171#issuecomment-528752754)。尝试做:
describe('Testing index.js...', () => {
it('Should return success', () => {
const promise = main();
Promise.resolve().then(() => jest.advanceTimersByTime(2000005));
return promise.then((res) => {
expect(res).toBe('success');
});
});
});
推荐阅读
- android - Volley 中的 POST 请求(使用 JSON 而不是字符串)
- r - 在 R 中对两个具有交叉连接的数据集使用 stringdist
- java - MapDB treemap.clear() 需要永远
- android - 有人能告诉我为什么这在 SQLITE 中是错误的吗
- javascript - 如何在 mongoOp 查找查询之外的节点 js 中打印结果数组?
- r - 用 NA 重新排列列
- c# - 如何应用 JsonExtensionData(字典
) 到另一个使用 JSON.Net 的对象 - python - 河内塔类型错误:“类型”对象不可下标
- python - Python3:如何重新设计嵌套类层次结构以更好地序列化和/或促进更好的模型/视图解耦
- android - Android 构建失败 - java.lang.IllegalArgumentException:对通配符的引用必须是数字 (*)