简体   繁体   English

Spring 启动 @MockMvcTest MockHttpServletResponse 总是返回空正文

[英]Spring boot @MockMvcTest MockHttpServletResponse always returns empty body

I'm struggling with a simple spring boot rest controller test which always return empty body response.我正在努力进行一个简单的 spring 启动 rest controller 测试,它总是返回空体响应。

Here is my test code looks like:这是我的测试代码:

@WebMvcTest(AdminRestController.class)
@AutoConfigureMockMvc(addFilters = false)
public class PatientsUnitTest {

    @Autowired
    private MockMvc mvc;

    @Autowired
    private ObjectMapper objectMapper;

    @MockBean
    private PatientsService patientsService;

    @MockBean
    private TherapistsService therapistsService;

    @MockBean
    private TherapySchedulesService therapySchedulesService;

    @Test
    public void canAddPatient() throws Exception {
        PatientsSaveRequestDto patientsSaveRequestDto = new PatientsSaveRequestDto();
        patientsSaveRequestDto.setName("Sofia");
        patientsSaveRequestDto.setPhone("01012345678");
        Patients patient = patientsSaveRequestDto.toEntity();

        when(patientsService.createPatient(patientsSaveRequestDto)).thenReturn(patient);

        final ResultActions actions = mvc.perform(post("/admin/patient")
                .contentType(MediaType.APPLICATION_JSON_VALUE)
                .characterEncoding(StandardCharsets.UTF_8.name())
                .content(objectMapper.writeValueAsString(patientsSaveRequestDto)))
                .andDo(print());

        actions
                .andExpect(status().isOk())
                .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE))
                .andExpect(jsonPath("name", is(patient.getName())))
                .andDo(print());
    }

My Controller:我的 Controller:

@RestController
@RequiredArgsConstructor
public class AdminRestController {
    private final PatientsService patientsService;
    private final TherapistsService therapistsService;
    private final TherapySchedulesService therapySchedulesService;

    @PostMapping("/admin/patient")
    @ResponseStatus(HttpStatus.OK)
    @Operation(summary = "Create a patient")
    public Patients cratePatient(
            @RequestBody @Valid PatientsSaveRequestDto patientsSaveRequestDto
    ) {
        return patientsService.createPatient(patientsSaveRequestDto);
    }

// PatientsService
@Transactional
    public Patients createPatient(PatientsSaveRequestDto patientsSaveRequestDto){
        return patientsRepository.save(patientsSaveRequestDto.toEntity());
    }

And this is the result of print():这是 print() 的结果:

MockHttpServletRequest:
      HTTP Method = POST
      Request URI = /admin/patient
       Parameters = {}
          Headers = [Content-Type:"application/json;charset=UTF-8", Content-Length:"53"]
             Body = {"name":"sofia","phone":"01012345678","tel":null}
    Session Attrs = {}

Handler:
             Type = com.ussoft.dosu.web.controller.admin.AdminRestController
           Method = com.ussoft.dosu.web.controller.admin.AdminRestController#cratePatient(PatientsSaveRequestDto)

Async:
    Async started = false
     Async result = null

Resolved Exception:
             Type = null

ModelAndView:
        View name = null
             View = null
            Model = null

FlashMap:
       Attributes = null

MockHttpServletResponse:
           Status = 200
    Error message = null
          Headers = []
     Content type = null
             Body = 
    Forwarded URL = null
   Redirected URL = null
          Cookies = []

As you can see the request is sent correctly but the response values are all null.如您所见,请求已正确发送,但响应值均为 null。

When i test the same controller using @SpringBootTest with Rest Assured it works fine.当我使用 @SpringBootTest 和 Rest 测试相同的 controller 时,确保它工作正常。

I'm using Spring boot 2.3.1, Junit5我正在使用 Spring 启动 2.3.1,Junit5


Edit - added PatientsSaveRequestDto编辑 - 添加了 PatientSaveRequestDto

@Getter
@Setter
@NoArgsConstructor
public class PatientsSaveRequestDto {
    @NotBlank(message = "이름은 필수 입력사항입니다.")
    private String name;

    private String phone;

    private String tel;

    public Patients toEntity(){
        return Patients.builder()
                .name(name)
                .phone(phone)
                .tel(tel)
                .build();
    }
}

You need to provide equals method for PatientsSaveRequestDto .您需要为PatientsSaveRequestDto提供 equals 方法。

When you execute a method on a mock, Mockito needs to check if any behaviour was specified for the arguments for which the method was called.当您在模拟上执行方法时,Mockito 需要检查是否为调用该方法的 arguments 指定了任何行为。

  • If the arguments match, the recorded result is returned,如果 arguments 匹配,则返回记录结果,
  • If the arguments don't match, default value of the method return type is returned (null for all Objects, zero for numerics, false for bools)如果 arguments 不匹配,则返回方法返回类型的默认值(所有对象为 null,数字为零,布尔为 false)

You recorded the behaviour with the following call:您使用以下调用记录了该行为:

when(patientsService.createPatient(patientsSaveRequestDto)).thenReturn(patient);

This means that the actual argument to createPatient will be compared to patientsSaveRequestDto with equals .这意味着createPatient的实际参数将与带有equalspatientsSaveRequestDto进行比较。

Note that this behaviour can be changed by the use of ArgumentMatchers .请注意,可以使用ArgumentMatchers更改此行为。

The patientsSaveRequestDto from your test and the actual argument to createPatient are not equal because:您的测试中的patientsSaveRequestDtocreatePatient的实际参数不相等,因为:

  • you didn't define the equals method你没有定义equals方法
  • they are different instances它们是不同的实例
  • thus, the inherited Object.equals returns false因此,继承的 Object.equals 返回 false

You have 2 different instances because you created a @WebMvcTest.您有 2 个不同的实例,因为您创建了一个 @WebMvcTest。 The patientsSaveRequestDto you send to the controller is first serialized to String and then deserialized, and this is how a second instance got created.您发送到 controller 的patientsSaveRequestDto首先被序列化为字符串,然后被反序列化,这就是创建第二个实例的方式。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 MockHttpServletResponse 主体为空 - MockHttpServletResponse body empty MockHttpServletResponse 为 Pageable 端点返回空正文 - MockHttpServletResponse returning empty body for Pageable endpoint JAVA - 得到空的 MockHttpServletResponse: body..但是它是 200 - JAVA - Getting empty MockHttpServletResponse: body..However it's 200 如何正确地将地图从角度客户端发送到请求正文中的spring boot controller? 收到的地图始终为空 - How to properly send map from angular client to spring boot controller in request body? Received map is always empty Spring Boot 测试 - MockHttpServletResponse getContentLength 返回 0 尽管有内容 - Spring Boot test - MockHttpServletResponse getContentLength return 0 despite of content MockMvc REST控制器-始终返回空主体 - MockMvc REST controller - always returns empty body Spring Boot 响应正文在 PostMan 中显示为空 - Spring boot response body is showing empty in PostMan ResponseBody 正在打印空体以进行弹簧启动测试 - ResponseBody is printing empty body for spring boot test @ApiResponse 响应体为空(Spring Boot) - @ApiResponse with empty response body (Spring Boot) Spring Boot总是返回404错误 - Spring boot always returns a 404 error
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM