WireMock 不直接抛异常,而是模拟错误响应(如500+自定义JSON体),客户端需通过ResponseErrorHandler等机制解析并主动throw自定义异常;需精准匹配请求、验证异常类型及内容。

WireMock 本身不直接触发客户端抛出自定义异常,它只负责模拟 HTTP 响应(包括错误状态码、错误响应体等);客户端是否抛异常、抛什么异常,取决于你自己的 HTTP 客户端代码(如 RestTemplate、Feign、OkHttp 等)如何处理响应。关键在于:WireMock 模拟出符合你预期的“错误响应”,然后客户端根据该响应主动解析并 throw 自定义异常。
1. 用 WireMock 返回错误 HTTP 状态码 + 自定义错误体
这是最常用且推荐的方式。比如模拟服务端返回 500 或 400,并附带 JSON 错误结构:
- 在测试中启动 WireMock(独立模式或 JVM 内嵌)
- 配置 stub,指定 status、headers 和 body:
stubFor(post("/api/order")
.willReturn(aResponse()
.withStatus(500)
.withHeader("Content-Type", "application/json; charset=utf-8")
.withBody("{\"code\": \"ORDER_FAILED\", \"message\": \"库存不足,请稍后重试\"}")));
这样客户端收到的就是一个标准的 500 响应,含你定义的错误字段,便于后续统一解析。
2. 客户端拦截响应并解析错误体,主动 throw 异常
以 Spring RestTemplate 为例,可自定义 ResponseErrorHandler:
- 实现
ResponseErrorHandler,重写hasError判断哪些状态码算“错误”(如 4xx/5xx) - 重写
handleError,用HttpMessageConverter解析响应体为你的错误对象(如ErrorResponse) - 再根据
ErrorResponse.code或message构造并抛出对应自定义异常(如OrderException)
Feign 用户则可通过 ErrorDecoder 实现类似逻辑;OkHttp 可在 Interceptor 中检查 response.code() 和 body。
3. 注意 WireMock 的匹配精度,避免误匹配
如果客户端发了多个相似请求(如带不同 query 或 body),需确保 stub 能精准命中目标请求:
- 用
withRequestBody(matchingJsonPath("$.userId", equalTo("123")))匹配 JSON 字段 - 用
withQueryParam("traceId", equalTo("abc"))匹配查询参数 - 启用 WireMock 日志(
WireMock.configureFor(...); WireMock.enableRecordMappings();)查看实际请求,辅助调试匹配规则
4. 验证异常是否被正确抛出(单元测试核心)
写 JUnit 测试时,重点验证两点:
- 调用接口后是否确实抛出了你期望的自定义异常类型(用
@Test(expected = OrderException.class)或assertThrows) - 异常消息或字段是否与 WireMock 返回的错误体一致(例如
exception.getMessage().contains("库存不足"))
不要只验证 HTTP 状态码——那只是 WireMock 的行为;你要验证的是整个链路:WireMock → 客户端响应处理 → 自定义异常抛出。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











