【问题标题】:Spring MockMvc is returning 200 instead of a 201. How to debug?Spring MockMvc 返回 200 而不是 201。如何调试?
【发布时间】:2020-03-24 02:39:31
【问题描述】:

我正在尝试使用 Spring MockMvc 测试具有多个 HTTP 动词的控制器。目前GETDELETE 按预期工作,但PUTPATCH 没有返回201,而应该返回。

PATCH 控制器设置如下:

@CustomRequestMapping(method = PATCH, value = "/{api-root}")
public ResponseEntity patch(@PathVariable(value = "api-root") String id, @RequestBody ApiRoot apiRoot) {
     return apiRootService.softUpdate(id, apiRoot);
}

@CustomRequestMapping... 注释只是将consumesproduces 设置为特定的内容类型。

上面引用的softUpdate() 方法执行以下操作:

public ResponseEntity softUpdate(String id, ApiRoot apiRoot) {
    if (apiRoot.getId() == null) {
        apiRoot.setId(id);
    }

    ApiRootDocument updated = softUpdate(apiRoot);
    return ResponseEntity
            .created(EscapeUtil.buildUrl(applicationProperties.getHostname(), applicationProperties.getPort(), id))
            .body(updated);
}

这是在 MockMvc 单元测试之外工作和测试的。它正确地向 Postman 返回了一个 201 Created,正文是作为 PATCH 的结果创建的新 JSON 对象。

我的测试设置为:

public void testPatchApiRootEndpoint() throws Exception {
    String testTitle = "New Test Title";

    // Mock the service call for softUpdate() to return 'created' in the same way that the method does
    when(apiRootService.softUpdate(TestData.apiRoot1.getId(), TestData.apiRoot1.withTitle(testTitle)))
            .thenReturn(ResponseEntity
                .created(URI.create(EscapeUtil.buildUrlString("localhost", "8001", TestData.apiRoot1.getId())))
                .body((ApiRootDocument) TestData.apiRoot1.withTitle(testTitle)));

    // Perform a patch update using a new title provided as key-value
    JsonObject titleJson = new JsonObject();
    titleJson.addProperty("title", testTitle);
    mockMvc.perform(patch("/{api-root}", TestData.apiRoot1.getId())
                .contentType(Constants.TAXII2_CONTENT_TYPE)
                .content(titleJson.toString()))
            .andExpect(status().isCreated());
}

这会导致返回 200,而不是 201。我真的很困惑,很难研究。大多数类似的问题是在期望 2XX 时发现 4XX 响应代码,解决方案通常与请求的设置有关。

我似乎能找到的唯一有趣的日志是:

09:48:25.064 [main] DEBUG org.springframework.test.web.servlet.TestDispatcherServlet - Servlet '' configured successfully
09:48:25.208 [main] DEBUG org.springframework.test.web.servlet.TestDispatcherServlet - DispatcherServlet with name '' processing PATCH request for [/api-root-1]
09:48:25.211 [main] DEBUG org.springframework.test.web.servlet.setup.StandaloneMockMvcBuilder$StaticRequestMappingHandlerMapping - Looking up handler method for path /api-root-1
09:48:25.219 [main] DEBUG org.springframework.test.web.servlet.setup.StandaloneMockMvcBuilder$StaticRequestMappingHandlerMapping - Returning handler method [public org.springframework.http.ResponseEntity xor.bcmc.flarecloud.apiroot.controller.ApiRootController.patch(java.lang.String,xor.bcmc.taxii2.resources.ApiRoot)]
09:48:25.388 [main] DEBUG org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor - Read [class xor.bcmc.taxii2.resources.ApiRoot] as "application/vnd.oasis.taxii+json;version=2.0" with [org.springframework.http.converter.json.MappingJackson2HttpMessageConverter@20921b9b]
09:48:25.428 [main] DEBUG org.springframework.test.web.servlet.TestDispatcherServlet - Null ModelAndView returned to DispatcherServlet with name '': assuming HandlerAdapter completed request handling
09:48:25.428 [main] DEBUG org.springframework.test.web.servlet.TestDispatcherServlet - Successfully completed request

【问题讨论】:

    标签: java spring spring-mvc


    【解决方案1】:

    看起来您的模拟调用不起作用。您可以轻松检查是否将值替换为 any():

    when(apiRootService.softUpdate(Mockito.any(), Mockito.any())
    .thenReturn(ResponseEntity
                    .created(URI.create(EscapeUtil.buildUrlString("localhost", "8001", TestData.apiRoot1.getId())))
                    .body((ApiRootDocument) TestData.apiRoot1.withTitle(testTitle)));
    

    我刚刚检查你是否使用了来自控制器的错误模拟返回 200 状态,但如果模拟正确我得到 201。

    【讨论】:

    • 谢谢,这确实有效,但我很好奇为什么 Mockito 和 Spring 无法检测到传入的实际参数值?无论如何,它可以工作并且涵盖了我需要它的代码,所以我会接受它。
    • Mockito.any() 在我的例子中只是为了方便检查,当然在现实生活中你应该检查实际值,例如 Mockito.eq(TestData.apiRoot1.getId()) 在你的情况下
    猜你喜欢
    • 2021-06-07
    • 2021-08-23
    • 2018-06-22
    • 1970-01-01
    • 2019-03-23
    • 2020-11-21
    • 2017-04-11
    • 2019-08-01
    • 2021-01-13
    相关资源
    最近更新 更多