MockHttpServletResponse 在测试中为空,尽管 Controller 工作正常

MockHttpServletResponse has empty in test, despite Controller working correctly

我正在使用 MockMvc 测试 @RestController POST 端点。 在此测试中,MockHttpServletResponse 内容始终为空且未设置内容类型。 我检查了控制器方法;它被调用并且 returns 正确的响应。 不过,在测试中,状态代码已正确设置为 201。

这是测试:

@Test
public void testBookCreation() throws Exception {
    var response = mockMvc.perform(
        MockMvcRequestBuilders
            .post("/books/create")
            .contentType(MediaType.APPLICATION_JSON)
            .content(
                jsonb.toJson(new Book("KR","K & R",5,8))
            )
    ).andExpect(
        MockMvcResultMatchers.status().isCreated()
    ).andExpect(
        MockMvcResultMatchers.content().contentTypeCompatibleWith(MediaType.APPLICATION_JSON)
    ).andExpect(
        MockMvcResultMatchers.jsonPath("$.author").exists()
    ).andDo((result)->{
        System.out.println(result.getResolvedException());
        System.out.println(result.getResponse());
    }).andReturn();
    }

这是控制器方法:

@PostMapping("/create")
@ResponseStatus(code=HttpStatus.CREATED,reason="Book created")
public Book makeBook(@RequestBody Book b ) {
    var res = bookRepository.save(b);
    System.out.println(res);
    return res;
}

我认为问题出在测试上,而不是控制器本身。

ResponseStatus 的文档说明如下:

Warning: when using this annotation on an exception class, or when setting the reason attribute of this annotation, the HttpServletResponse.sendError method will be used.

意味着您将收到以下形状的响应,无论在您的控制器中发送的响应是什么负载

{
  "timestamp":"",
  "status":201,
  "error":"Created",
  "message":"",
  "path":"/books/create"
}

然后您应该删除 ReponseStatus 注释的 reason 字段:

@PostMapping("/create")
@ResponseStatus(code=HttpStatus.CREATED)
public Book makeBook(@RequestBody Book b ) {
    var res = bookRepository.save(b);
    System.out.println(res);
    return res;
}