如何在MockMvc测试中兼容两种不同的响应状态码?
合并两种可接受响应的MockMvc集成测试方案
你可以通过先执行请求获取结果,再根据状态码分支处理断言的方式,把两种情况合并到单个测试中,完全不需要RestTemplate。核心思路是先拿到请求的MvcResult,再判断状态码类型,针对性执行验证逻辑:
import org.springframework.test.web.servlet.get import org.springframework.test.web.servlet.result.MockMvcResultMatchers.* import org.springframework.http.MediaType import com.jayway.jsonpath.JsonPath // 单个测试方法内实现分支验证 @Test fun testMyResourceEndpoint() { // 执行请求并获取结果 val mvcResult = mockMvc.get("/myresource") { contentType = MediaType.APPLICATION_JSON accept = MediaType.APPLICATION_JSON }.andReturn() val statusCode = mvcResult.response.status when { // 状态码200时,执行完整的JSON验证 statusCode == 200 -> { mvcResult.response.apply { assertEquals(MediaType.APPLICATION_JSON_VALUE, contentType) val jsonBody = JsonPath.parse(contentAsString) assertEquals("Hello SO", jsonBody.read("$.greeting")) } } // 状态码5xx时,无需额外操作,只要状态码符合就通过 statusCode in 500..599 -> {} // 其他状态码直接断言失败 else -> error("Unexpected status code: $statusCode") } }
关键说明:
- 先用
andReturn()获取请求结果MvcResult,避免直接执行断言导致测试提前失败 - 通过
when分支做状态码判断:- 200场景下,直接对响应对象做JSON格式、字段值的校验
- 5xx场景下,不执行任何额外断言,只要状态码在500-599区间内,测试就通过
- 其他非预期状态码直接抛出错误,确保测试只接受预设的两种情况
- 如果你的接口是异步类型,可以改用
asyncDispatch重新调度请求后再做断言,示例如下:
// 异步接口的适配写法 when { statusCode == 200 -> { mockMvc.perform(asyncDispatch(mvcResult)) .andExpect { status { isOk() } content { contentType(MediaType.APPLICATION_JSON) } jsonPath("$.greeting", `is`("Hello SO")) } } statusCode in 500..599 -> { mockMvc.perform(asyncDispatch(mvcResult)) .andExpect { status { is5xxServerError() } } } else -> error("Unexpected status code: $statusCode") }
这样就能在单个测试用例里同时兼容两种可接受的响应,既保证200场景的验证完整性,又能在依赖服务故障(返回5xx)时让测试通过。
内容的提问来源于stack exchange,提问作者Paulo Merson
相关产品推荐
相关产品推荐

