繁体   English   中英

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

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

我正在努力进行一个简单的 spring 启动 rest controller 测试,它总是返回空体响应。

这是我的测试代码:

@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());
    }

我的 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());
    }

这是 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 = []

如您所见,请求已正确发送,但响应值均为 null。

当我使用 @SpringBootTest 和 Rest 测试相同的 controller 时,确保它工作正常。

我正在使用 Spring 启动 2.3.1,Junit5


编辑 - 添加了 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();
    }
}

您需要为PatientsSaveRequestDto提供 equals 方法。

当您在模拟上执行方法时,Mockito 需要检查是否为调用该方法的 arguments 指定了任何行为。

  • 如果 arguments 匹配,则返回记录结果,
  • 如果 arguments 不匹配,则返回方法返回类型的默认值(所有对象为 null,数字为零,布尔为 false)

您使用以下调用记录了该行为:

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

这意味着createPatient的实际参数将与带有equalspatientsSaveRequestDto进行比较。

请注意,可以使用ArgumentMatchers更改此行为。

您的测试中的patientsSaveRequestDtocreatePatient的实际参数不相等,因为:

  • 你没有定义equals方法
  • 它们是不同的实例
  • 因此,继承的 Object.equals 返回 false

您有 2 个不同的实例,因为您创建了一个 @WebMvcTest。 您发送到 controller 的patientsSaveRequestDto首先被序列化为字符串,然后被反序列化,这就是创建第二个实例的方式。

暂无
暂无

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM