我有一个主函数,它调用两个异步函数,中间有睡眠函数。这是一个基本的例子:
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.rrunOnlyEndingTimers(
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问题的解决方案,还有很多关于堆栈溢出的问题,但似乎没有一个解决方案奏效。
我正在使用笑话25.5.4
编辑:我还试着将jest.advanceTimersBytTime((中的值增加到一天。并尝试在describeasync中制作函数。
我最近也遇到过类似的问题,对我来说有效的方法是从异步调用中提前计时器。似乎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');
});
});
});
async
、原始承诺和done
回调不应在测试中一起使用。这是一个常见的迹象,表明开发人员对Jest异步测试并不完全满意,这会导致测试容易出错。
original的问题是promise.then(...)
promise被忽略,因为它没有被链接。异步测试应该返回一个promise,以便将其链接起来。
CCD_ 4和CCD_ 5返回立即解决并产生一个节拍延迟而不是1秒延迟的承诺。应该考虑这一点,因为否则会出现竞争条件,setTimeout
在advanceTimersByTime
之后被调用。
应该是:
test('Should return success', async() => {
const promise = index();
await null; // match delay from await func1()
jest.advanceTimersByTime(2000000);
const response = await promise;
expect(response).toBe('success');
});