async/await测试需声明测试函数为async,直接await异步操作,避免漏await导致假成功,配合expect().rejects或try/catch覆盖异常,及时清理定时器等副作用。

在 JavaScript 异步代码测试中,async 与 await 是让测试更简洁、可读性更强的关键工具。只要测试函数本身是 async 的,你就能直接 await 被测的异步函数,无需手动处理 Promise 链或回调。
测试函数必须声明为 async
这是最基础但容易忽略的一点:Jest、Vitest 或其他主流测试框架都要求,若要在测试中使用 await,测试回调函数本身必须用 async 声明。
- ✅ 正确写法:
const user = await fetchUser(123);
expect(user.name).toBe('Alice');
});
- ❌ 错误写法(会报语法错误):
const user = await fetchUser(123); // SyntaxError: await is only valid in async function
});
无需 return Promise,但不能忘记 await
旧写法中常靠 return fetchUser(123).then(...) 让测试框架等待 Promise 完成;现在只需 await,框架会自动等待该 Promise settle。但若漏掉 await,测试会立即通过(因为返回的是未 resolve 的 Promise),导致“假成功”。
- ⚠️ 危险写法(测试可能跳过断言):
fetchUser(123).then(user => expect(user.name).toBe('Alice')); // ❌ 没 await,断言不被等待
});
- ✅ 推荐写法(清晰、安全):
const user = await fetchUser(123);
expect(user.name).toBe('Alice');
});
配合 mock 和 error 测试更完整
真实场景中,异步函数可能失败。用 await + try/catch 或 expect(...).rejects 可自然覆盖异常路径。
- 测试成功路径(同上)
- 测试失败路径(推荐用
.rejects,语义清晰):
await expect(fetchUser(999)).rejects.toThrow('Not Found');
});
- 或手动 try/catch:
try {
await fetchUser(999);
fail('should have thrown');
} catch (err) {
expect(err.message).toBe('Not Found');
}
});
注意清理副作用(如定时器、未关闭连接)
某些异步操作(如 setTimeout、WebSocket、轮询)可能在测试结束后仍在运行,造成内存泄漏或干扰后续测试。务必在 afterEach 或 jest.clearAllTimers() 中清理。
- 例如,被测函数内部用了
setTimeout:
jest.useFakeTimers();
});
afterEach(() => {
jest.useRealTimers();
});
test('delays response by 100ms', async () => {
const result = await delayedGreeting();
expect(result).toBe('Hello');
jest.runAllTimers(); // 主动推进 timer
});
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











