javascript mock 中模拟复杂错误需还原真实请求失败的完整上下文,包括状态码、响应体、headers、堆栈及自定义属性;推荐用 response 构造函数、扩展 error 实例或 msw 精准控制多场景错误响应,并确保原型链与业务约定一致。

在 JavaScript Mock 中模拟复杂错误对象和状态码,关键不是只抛出一个字符串或简单 Error 实例,而是要还原真实请求失败时的完整上下文——包括 HTTP 状态码、响应体结构、headers、堆栈信息甚至自定义属性。这在测试错误边界、错误提示、重试逻辑或状态码分发处理时非常必要。
用 Response 构造函数模拟带状态码的错误响应
现代 fetch mock(如 jest-fetch-mock 或 msw)支持返回真实的 Response 对象。你可以构造一个 status 非 2xx 的 Response,并注入 JSON 错误体:
- 使用
new Response(JSON.stringify({ message: "Invalid token", code: "AUTH_001" }), { status: 401, statusText: "Unauthorized" }) - 可选添加 headers:
{ headers: { "Content-Type": "application/json" } } - 这样被测代码中调用
response.json()和检查response.status的行为完全符合真实流程
手动构造带扩展属性的 Error 实例(适用于 Axios 或自定义封装)
如果被测代码捕获的是被拦截/包装后的错误(比如 Axios 的 error.response),需模拟整个错误结构:
- 创建一个普通对象模拟
error.response,包含status、statusText、data、headers、config - 再用
Object.assign(new Error("Request failed"), { response: mockResponse })赋予错误实例额外字段 - 确保关键属性可枚举(避免用
defineProperty隐藏),否则断言err.response?.status可能为undefined
用 msw 拦截并精准控制不同场景的错误响应
msw 是目前最灵活的方案,可按 URL、method、甚至请求 body 区分错误类型:
- 对同一接口,mock 多个 handler:一个返回 400(校验失败),一个返回 503(服务不可用),一个返回网络异常(
ctx.fetchError()) - 在 handler 中动态生成错误响应:
return new HttpResponse(null, { status: 422, headers: { "X-Retry-After": "60" } }) - 配合
vi.mock或直接在 test 中启用 msw,能覆盖从网络层到业务层的全链路错误路径
注意错误堆栈与原型链一致性
某些工具(如 Sentry)依赖 error instanceof Error 或 error.stack 做分类。Mock 时别用纯对象替代:
- 避免
{ message: "...", status: 404 }这种 plain object —— 它不是 Error 实例 - 优先用
new Error()扩展,或继承Error类(如class ApiError extends Error { constructor(msg, status) { super(msg); this.status = status; } }) - 若需保留原始堆栈,可在构造时调用
Error.captureStackTrace?.(this, ApiError)(Node.js)或手动赋值this.stack
不复杂但容易忽略:状态码和错误体必须匹配业务约定,比如 400 通常带 field-level 校验信息,401/403 需触发登出,5xx 要有重试机制 —— Mock 正是为了验证这些分支是否真被触发。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











