我试图了解异步测试在 Jest 中的工作原理。
我想做的与 Jest 文档中的示例类似。这很好用..
function doAsync(c) {
c(true)
}
test('doAsync calls both callbacks', () => {
expect.assertions(2);
function callback1(data) {
expect(data).toBeTruthy();
}
function callback2(data) {
expect(data).toBeTruthy();
}
doAsync(callback1);
doAsync(callback2);
});
但是我想延迟回调调用,所以我尝试了这个....
function doAsync(c) {
setTimeout(() => {
console.log('timeout fired')
c(true)
}, 1000)
}
但测试失败并显示消息
Expected two assertions to be called but received zero assertion calls.
。
日志消息“超时已触发”不会出现在控制台中。
请有人能解释一下为什么失败吗?
您需要使用jest的计时器模拟https://jestjs.io/docs/en/timer-mocks
首先告诉 jest 使用模拟计时器,然后在测试中运行计时器。
它看起来像:
function doAsync(c) {
setTimeout(() => {
c(true)
}, 1000)
}
jest.useFakeTimers()
test('doAsync calls both callbacks', () => {
expect.assertions(2);
function callback1(data) {
expect(data).toBeTruthy();
}
function callback2(data) {
expect(data).toBeTruthy();
}
doAsync(callback1);
doAsync(callback2);
jest.runAllTimers(); // or jest.advanceTimersByTime(1000)
});
使用
jest.runAllTimers();
可能会导致以下错误:
跑了100000个计时器,还有更多!假设我们已经击中了 无限递归和救助...
在浏览完JEST计时器模拟文档之后,我发现
setTimeout
进入文档中提到的无限递归。建议使用jest.runOnlyPendingTimers()
,这样可以解决无限递归错误。
仅快进并耗尽当前待处理的计时器 (但不是在此过程中创建的任何新计时器)
jest.runOnlyPendingTimers();
就我而言,它仅在我使用
node:timers/promises
时才有效。示例:
代码不起作用:
const sleep = (index: number) => {
return new Promise((resolve) => {
setTimeout(() => {
resolve({});
}, index * 500);
});
};
代码工作:
const sleep = (index: number) => {
return setTimeout(index * 500);
};
在测试用例中使用以下代码作为 setTime out。
it('saveSubscription', () => {
function doAsync(c) {
setTimeout(() => {
component.addSubscription();
expect(component.subscription.freq).toEqual('immediate');
component.saveSubscription();
expect(component.subscription.name).toBe('Untitled 1');
}, 30000);
}
});