Spring MVC 如何在MockMvc测试中接受两个不同的状态码?

sq1bmfud  于 2023-03-08  发布在  Spring
关注(0)|答案(2)|浏览(146)

bounty将在2天后过期。回答此问题可获得+50的声誉奖励。Paulo Merson正在寻找来自声誉良好来源的答案:答案应该要么与MockMvc一起工作,要么清楚地表明MockMvc不支持预期的验证。

我需要在集成测试中测试HTTP端点。有两种可接受的响应:

*状态代码200,在这种情况下,我需要检查内容是否为JSON,并在正文中查找特定的元素值,或者
*状态代码是5xx,在这种情况下,我什么也不做(目标是当我调用的服务没有响应时,我的测试不会失败)。

我知道如何分别测试每个可接受的响应。例如(Kotlin):

mockMvc.get("/myresource") {
        contentType = MediaType.APPLICATION_JSON
        accept = MediaType.APPLICATION_JSON
    }.andExpect {
        status { isOk() }
        content { contentType(MediaType.APPLICATION_JSON) }
        jsonPath("$.greeting", `is`("Hello SO"))
    }

以及:

mockMvc.get("/myresource") {
        contentType = MediaType.APPLICATION_JSON
        accept = MediaType.APPLICATION_JSON
    }.andExpect {
        status { is5xxServerError() }
    }

如何将两个可接受的回答组合在一个测试中?
我希望我不需要求助于RestTemplate

wribegjk

wribegjk1#

java :

import static org.hamcrest.Matchers.anyOf;
import static org.hamcrest.Matchers.oneOf;
import static org.hamcrest.Matchers.allOf;

mockMvc.stuff().andExpect(status().is(oneOf(200, 503)))

mockMvc.stuff()
       .andExpect(status().is(anyOf(allOf(lessThan(505), greaterThan(500)),
                                    allOf(lessThan(205), greaterThan(200)))));

status()之后的is()是这个。我写的不一定是用Hamcrest匹配器(有很多可供选择)做这个的最好方法。而且,你可能最好自己写。但这是总体思路。

62o28rlo

62o28rlo2#

这并不像接受两个状态码那么简单:根据实际情况,可能需要进一步Assert内容和json路径,所以这个场景比看起来要复杂得多,我怀疑内置的ResultMatchers是否支持它,这个场景还测试两个完全不同的结果,这对在spring测试项目中添加这样的支持没有帮助。
也就是说,有一些方法可以构建期望来有条件地执行Assert:

mockMvc.perform(get("/myresource"))
       .andExpect(status().is(anyOf(is(HttpStatus.OK), new CustomMatcher<>("status should be 5xx") {
           @Override
           public boolean matches(Object status) {
               return status instanceof Integer
                 && HttpStatus.Series.SERVER_ERROR.equals(HttpStatus.valueOf((int) status).series());
                }
            })))
       .andExpect(mvcResult -> {
                if (mvcResult.getResponse().getStatus() == HttpStatus.OK.value()) {
                    content().contentType(MediaType.APPLICATION_JSON).match(mvcResult);
                    jsonPath("$.greeting", is("Hello SO")).match(mvcResult);
                }
       })

这可转化为:

  • 我希望状态为200或5xx错误,
  • 我希望如果状态正常,则内容与我的期望值匹配

相关问题