async/await 编写异步测试的核心是将测试函数声明为 async,直接 await 被测逻辑,用 expect(...).rejects 验证错误,避免忽略 promise 或误用 done(),并妥善清理 mock 和定时器。

在 JavaScript 测试中,用 async 与 await 编写异步测试用例,核心是让测试函数本身支持异步、正确等待 Promise 完成,并避免手动调用 done() 或错误地忽略返回值。
测试函数必须声明为 async
主流测试框架(如 Jest、Vitest、Jasmine)都支持将测试回调函数标记为 async。这样你就能直接 await 被测的异步逻辑,无需额外包装或回调嵌套。
- Jest 中写法:
test('fetches user', async () => { ... }) - Vitest 同样支持:
it('sends email', async () => { ... }) - ⚠️ 注意:不能只在内部
await却不把外层函数设为async,否则测试会提前结束,导致断言失效
直接 await 被测函数,不用 .then() 或 done()
传统 Promise 风格常写 return fetchUser().then(...) 或传入 done 回调,既冗长又易出错。用 async/await 后可大幅简化:
Java项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...
- ✅ 推荐:
const user = await fetchUser(123); expect(user.name).toBe('Alice'); - ❌ 避免:
fetchUser(123).then(user => expect(user.name).toBe('Alice'));(Promise 被忽略,测试不等待) - ❌ 避免:
fetchUser(123).then(user => { expect(user.name).toBe('Alice'); done(); });(冗余且易漏掉done())
正确处理异步错误(比如 expect 抛出异常)
异步操作失败时(如 API 返回 404、数据库连接失败),往往以 rejected Promise 形式抛出错误。要验证这类行为,不能直接 await 并期望它成功,而要用 expect(...).rejects 断言:
await expect(fetchUser(999)).rejects.toThrow('Not Found');await expect(savePost({})).rejects.toHaveProperty('message', 'Validation failed');- ⚠️ 不要用
try/catch+expect(error)手动捕获——虽可行但啰嗦,且容易漏掉catch分支的断言覆盖
清理异步副作用(如 mock、定时器、网络请求)
异步测试常涉及 mock 函数、模拟 API、启动定时器等。若不清理,可能污染后续测试。建议在 beforeEach 或 afterEach 中统一管理:
- Jest 中重置 mock:
jest.clearAllMocks()或mockFn.mockReset() - 清除挂起的定时器:
jest.useFakeTimers(); afterEach(() => jest.runOnlyPendingTimers()); - Vitest 中可用
vi.restoreAllMocks()和vi.clearAllMocks() - 若测试中启用了真实网络请求(如用
fetch),推荐用msw或vitest-fetch-mock拦截并复位
不复杂但容易忽略的是:确保所有异步路径都被显式等待,包括 setup、teardown 和被测逻辑本身。只要测试函数是 async,且所有关键 Promise 都被 await 或 expect(...).resolves/rejects 包裹,测试就既清晰又可靠。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










