[英]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 指定了任何行为。
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
的实际参数将与带有equals
的patientsSaveRequestDto
进行比较。
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:您的测试中的
patientsSaveRequestDto
和createPatient
的实际参数不相等,因为:
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.