在setTimeout之前和之后使用异步函数调用进行Jest



我有一个主函数,它调用两个异步函数,中间有睡眠函数。这是一个基本的例子:

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秒延迟的承诺。应该考虑这一点,因为否则会出现竞争条件,setTimeoutadvanceTimersByTime之后被调用。

应该是:

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');
});

最新更新