单元测试中对 async/await 函数断言,需将测试函数声明为 async 并直接 await 被测函数,避免 done 回调或 then 链;断言拒绝时用 await expect(fn()).rejects.xxx;异步依赖须 mock Promise 行为。

在单元测试中对 async/await 函数做断言,核心是让测试框架等待 Promise 完成后再执行断言。只要测试函数本身是 async 的,并且正确 await 被测异步逻辑,就能自然处理异步断言。
测试函数必须声明为 async
这是最关键的一步。Jest、Vitest、Jasmine 等主流框架都支持 async 测试函数,但前提是测试回调(如 it 或 test 的第二个参数)必须是 async 函数。
- ✅ 正确写法:用
async () => { ... }包裹测试体 - ❌ 错误写法:忘记加
async,或只await但不声明函数为 async
例如 Jest 中:
test('fetches user data', async () => {
const result = await fetchUserData(); // 假设这是个 async 函数
expect(result.name).toBe('Alice');
});
直接 await 被测函数,不要用 done 或 then 链
旧式回调风格(如传入 done 参数)容易出错,也破坏 async/await 的可读性。现代测试应避免手动调用 done() 或嵌套 .then()。
立即学习“Java免费学习笔记(深入)”;
- ✅ 推荐:直接
await调用,然后写同步风格的expect - ❌ 不推荐:
return fetchUserData().then(...)或done()回调
错误示例(Jest):
// ❌ 混用风格,易漏掉 done() 或抛错时不调用 done()
test('fails if API is down', (done) => {
fetchUserData().catch(err => {
expect(err.message).toContain('network');
done();
});
});
正确写法:
// ✅ 清晰、自动处理 resolve/reject
test('fails if API is down', async () => {
await expect(fetchUserData()).rejects.toThrow('network');
});
断言 Promise 拒绝要用 expects.rejected
验证异步函数抛出错误时,不能直接 await fn() 再 expect —— 因为它会抛出异常导致测试失败。应使用测试框架提供的断言工具来“预期拒绝”。
- Jest:用
await expect(fn()).rejects.toEqual(...)或.toThrow(...) - Vitest:语法相同,
await expect(fn()).rejects.toThrow(...) - 注意:不要写成
expect(await fn()).toThrow()—— 这会在拒绝时直接报错
示例:
test('throws on invalid id', async () => {
await expect(getUser(999999)).rejects.toMatchObject({
status: 404,
message: 'Not Found'
});
});
模拟异步依赖(如 fetch、API 调用)
真实网络请求不可控,需用 mock 替换。重点是 mock 返回一个 Promise,并控制其 resolve 或 reject 行为。
- Jest:用
jest.mock('node-fetch')或mockResolvedValue()/mockRejectedValue() - Vitest:用
vi.mock()+vi.fn().mockResolvedValue() - 确保 mock 的 Promise 在测试中被 await 触发,否则断言可能跑在 mock 设置前
例如(Jest):
beforeEach(() => {
global.fetch = jest.fn();
});
test('shows loading state then success', async () => {
fetch.mockResolvedValue({ json: () => Promise.resolve({ id: 1, name: 'Bob' }) });
const result = await loadUserProfile();
expect(result.name).toBe('Bob');
});


















