JavaScript单元测试中Mock async函数需用jest.fn()返回可控Promise:成功用mockResolvedValue,失败用mockRejectedValue;模块函数用jest.mock()自动Mock;精细控制用mockImplementation;全局Mock后须用jest.restoreAllMocks清理。

在 JavaScript 单元测试中 Mock async 函数,核心是让被测代码调用的是你控制的“假函数”,而不是真实发起网络请求或执行耗时操作的函数。关键在于:Mock 返回一个 Promise,并控制它的解析值(resolve)或拒绝原因(reject),同时确保测试能正确等待它完成。
用 jest.fn() 返回 Promise
最常用、最直接的方式是用 Jest 的 jest.fn() 手动返回一个 Promise:
- 模拟成功场景:用
mockResolvedValue(value) - 模拟失败场景:用
mockRejectedValue(error)
例如,假设你有一个调用 API 的函数:
async function fetchUser(id) {
const res = await fetch(`/api/users/${id}`);
return res.json();
}
在测试中可以这样 Mock:
立即学习“Java免费学习笔记(深入)”;
test('fetches user successfully', async () => {
const mockData = { id: 1, name: 'Alice' };
global.fetch = jest.fn().mockResolvedValue({
json: jest.fn().mockResolvedValue(mockData)
});
const user = await fetchUser(1);
expect(user).toEqual(mockData);
expect(fetch).toHaveBeenCalledWith('/api/users/1');
});
Mock 模块里的 async 函数(如 API 工具函数)
如果 fetchUser 是从某个模块导出的函数(比如 api.js),推荐用 jest.mock() 自动 Mock 整个模块:
// api.js
export async function getUser(id) {
const res = await fetch(`/api/users/${id}`);
return res.json();
}
// api.test.js
import { getUser } from './api';
jest.mock('./api'); // 自动 Mock,所有导出函数变成 jest.fn()
test('calls getUser and resolves', async () => {
const mockUser = { id: 42, name: 'Bob' };
getUser.mockResolvedValue(mockUser); // 注意:这里 mockResolvedValue 是给函数本身用的
const result = await getUser(42);
expect(result).toEqual(mockUser);
});
⚠️ 注意:这种写法要求 getUser 是 async function 或返回 Promise;如果是普通函数里 return fetch(...).then(...),也一样适用 —— 只要它返回 Promise,mockResolvedValue 就生效。
需要控制 resolve/reject 时机?用 mockImplementation
当你要更精细地控制行为(比如延迟、多次不同响应、或基于参数返回不同结果),就用 mockImplementation 手动返回 Promise:
- 返回带
setTimeout的 Promise 实现延迟 - 根据入参决定 resolve 还是 reject
- 连续调用返回不同值(
mockResolvedValueOnce等)
test('handles network error', async () => {
const error = new Error('Failed to fetch');
fetch.mockImplementation(() =>
Promise.reject(error)
);
await expect(fetchUser(999)).rejects.toThrow('Failed to fetch');
});
别忘了清理 Mock(尤其全局对象)
Mock 全局对象(如 fetch、localStorage)后,建议在每个测试后还原,避免污染其他测试:
beforeEach(() => {
fetch.mockClear(); // 清空调用记录和返回值
});
// 或在 test 内部用
afterEach(() => {
jest.restoreAllMocks(); // 推荐,一键恢复所有 mock
});


















