javascript异步测试中模拟接口延迟的核心是用promise+settimeout构建可控异步响应,替代真实请求;可配合jest mock fetch、abortcontroller验证超时容错,严禁使用同步阻塞方式。

在 JavaScript 异步测试中模拟接口网络延迟,核心是**用可控的异步行为替代真实请求**,既保证测试可重复、不依赖外部服务,又贴近真实延迟场景。不需要启动服务器或 mock 后端,纯前端即可完成。
用 Promise + setTimeout 构建可配置的延迟响应
这是最轻量、最通用的方式。把 fetch 或 axios 调用替换成一个返回 Promise 的函数,内部用 setTimeout 模拟等待时间:
- 定义一个模拟函数,接收延迟毫秒数和是否成功的标志
- 在 setTimeout 回调中 resolve 或 reject,模拟成功响应或网络错误
- 测试时直接调用该函数,而非真实 API,延迟精确可控
示例:
const mockApi = (delay = 1000, shouldFail = false) =>
new Promise((resolve, reject) =>
setTimeout(() =>
shouldFail
? reject(new Error('Network timeout'))
: resolve({ data: 'mock response', timestamp: Date.now() }),
delay
)
);在测试框架中替换真实请求(如 Jest 中 mock fetch)
现代测试通常需要隔离外部依赖。以 Jest 为例,可全局 mock window.fetch,让它返回你定义的延迟 Promise:
- 在 test setup 文件中统一 mock fetch,避免每个测试重复写
- 利用 jest.fn() 返回自定义 Promise,支持不同延迟、状态码、响应体
- 配合 waitFor 或 async/await 断言,验证加载态、错误提示、数据渲染等行为
示例(Jest):
beforeAll(() => {
global.fetch = jest.fn().mockImplementation((url) =>
mockApi(url.includes('error') ? 500 : 1000, url.includes('error'))
);
});用 AbortController 配合超时逻辑验证容错能力
仅模拟延迟还不够,真实接口还有超时机制。测试中应覆盖“请求未完成但已超时”的场景:
- 在 mock 函数里不立即 resolve,而是监听 signal.aborted
- 当 controller.abort() 被调用时,主动 reject 并抛出 AbortError
- 这样能验证组件是否正确处理了 abort 逻辑,比如清空 loading 状态、忽略过期响应
这比单纯延后 resolve 更贴近浏览器 fetch 的实际行为。
避免常见陷阱:不要用同步 sleep 或 while 循环
有些开发者尝试用循环阻塞主线程来“模拟延迟”,例如:
while (Date.now() - start
这会破坏 JavaScript 的异步模型,使微任务无法执行、定时器失准、甚至让整个测试套件挂起。所有延迟必须基于非阻塞机制(setTimeout、Promise、queueMicrotask)。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











