[英]Jest with async function calls before and after setTimeout
我有一個主 function 調用兩個異步函數,兩者之間有睡眠 function。 這是一個基本示例:
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() 中的值增加到一天。 並且還嘗試在描述異步中制作 function。
我最近遇到了類似的問題,對我有用的是從異步調用中推進計時器。 似乎 jest 不支持在 promise 中設置計時器(參見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
, raw promises 和done
回調不應該在測試中一起使用。 這是開發人員對 Jest 異步測試並不完全滿意的一個常見跡象,這會導致測試容易出錯。
original 的問題是promise.then(...)
promise 被忽略,因為它沒有被鏈接。 異步測試應返回 promise 以便將其鏈接。
func1
和func2
返回立即解決並產生一個滴答聲延遲而不是 1 秒延遲的承諾。 應該考慮到這一點,因為否則會出現在advanceTimersByTime
之后調用setTimeout
的競爭條件。
它應該是:
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');
});
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.