如何在Spring Boot应用程序中测试post和put方法



我正在为Spring REST教程中的应用程序编写测试(https://spring.io/guides/tutorials/rest/),到目前为止还很清楚,但我在尝试测试我的post-and-put方法时遇到了困难(用get everything可以,用delete可能也可以,但不是100%确定(:

@Test
public void getEmployeesStatusIsOk() throws Exception {
mockMvc.perform(MockMvcRequestBuilders.get("/employees"))
.andExpect(status().is2xxSuccessful());
}
@Test
public void deleteEmployeeStatusIsOk() throws Exception {
var employee = getTestEmployee();
employee.setId(10L);
given(this.employeeRepository.existsById(any())).willReturn(Boolean.TRUE);
mockMvc.perform(MockMvcRequestBuilders.delete("/employees/{id}", 10L))
.andExpect(status().is2xxSuccessful());
}
@Test
public void postEmployeeStatusIsOk() throws Exception {
given(this.mockMvc.perform(MockMvcRequestBuilders.post(any()))).willReturn((ResultActions) ResponseEntity.status(HttpStatus.valueOf("Ok")));
mockMvc.perform(MockMvcRequestBuilders.post("/employees"))
.andExpect(status().is2xxSuccessful());
}
@Test
public void putEmployeeStatusIsOk() throws Exception
{
var employee = getTestEmployee();
employee.setId(1L);
mockMvc.perform( MockMvcRequestBuilders
.put("/employees/{id}", 1L)
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(employee))
.accept(MediaType.APPLICATION_JSON))
.andExpect(status().is2xxSuccessful());
}

我也会把方法留在这里,以防你需要看一看:

@GetMapping("/employees")
public CollectionModel<EntityModel<Employee>> all() {
List<EntityModel<Employee>> employees = repository.findAll().stream()
.map(assembler::toModel).collect(Collectors.toList());
return CollectionModel.of(employees, linkTo(methodOn(EmployeeController.class).all()).withSelfRel());
}
@PostMapping("/employees")
ResponseEntity<?> newEmployee(@RequestBody Employee newEmployee) {
EntityModel<Employee> entityModel = assembler.toModel(repository.save(newEmployee));
return ResponseEntity //
.created(entityModel.getRequiredLink(IanaLinkRelations.SELF).toUri()) //
.body(entityModel);
}

@GetMapping("/employees/{id}")
public EntityModel<Employee> one(@PathVariable Long id) {
Employee employee = repository.findById(id) //
.orElseThrow(() -> new EmployeeNotFoundException(id));
return assembler.toModel(employee);
}
@PutMapping("/employees/{id}")
ResponseEntity<?> replaceEmployee(@RequestBody Employee newEmployee, @PathVariable Long id) {
Employee updatedEmployee = repository.findById(id) //
.map(employee -> {
employee.setName(newEmployee.getName());
employee.setRole(newEmployee.getRole());
return repository.save(employee);
}) //
.orElseGet(() -> {
newEmployee.setId(id);
return repository.save(newEmployee);
});
EntityModel<Employee> entityModel = assembler.toModel(updatedEmployee);
return ResponseEntity //
.created(entityModel.getRequiredLink(IanaLinkRelations.SELF).toUri()) //
.body(entityModel);
}
@DeleteMapping("/employees/{id}")
ResponseEntity<?> deleteEmployee(@PathVariable Long id) {
if (!repository.existsById(id)) {
throw new EmployeeNotFoundException(id);
}
repository.deleteById(id);
return ResponseEntity.noContent().build();
}

错误消息的开始:

java.lang.IollegalArgumentException:需要"url">

放入

org.springframework.web.util.NestedServlet异常:请求处理失败;嵌套异常为java.lang.NullPointerException:无法调用"org.springframework.hateoas.EntityModel.getRequiredLink(org.springfframework.hateoas.LinkRelation("因为";实体模型";为空

提前感谢您。

首先,出于某种原因,我需要通过@TestConfiguration声明EmployeeModelAssembler,而不是通过@MockBean:

@TestConfiguration
static class ModelAssemblerConfiguration {
@Bean
public EmployeeModelAssembler getEmployeeAssembler() {
return new EmployeeModelAssembler ();
}
}

此外,还需要添加两个模拟测试,当然还有一个用于post-body的内容:

@Test
public void postEmployeeStatusIsOk() throws Exception {
var employee = getTestEmployee();
given(this.employeeRepository.save(any())).willReturn(getTestEmployee());
mockMvc.perform(MockMvcRequestBuilders.post("/employees")
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(employee))
.accept(MediaType.APPLICATION_JSON))
.andExpect(status().is2xxSuccessful());
}
@Test
public void putEmployeeStatusIsOk() throws Exception
{
given(this.employeeRepository.findById(any())).willReturn(Optional.of(getTestEmployee()));
given(this.employeeRepository.save(any())).willReturn(getTestEmployee());
var employee = getTestEmployee();
employee.setId(10L);
mockMvc.perform( MockMvcRequestBuilders
.put("/employees/{id}", 1L)
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(employee))
.accept(MediaType.APPLICATION_JSON))
.andExpect(status().is2xxSuccessful())
.andExpect(MockMvcResultMatchers.jsonPath("$.firstName").value("Max"));

还有get测试的mock和value检查,因为它实际上什么都没做(返回null,全部是因为EmployeeModelAssembler不工作(:

@Test
public void getEmployeesStatusIsOk() throws Exception {
given(this.employeeRepository.findAll()).willReturn(List.of(getTestEmployee()));
mockMvc.perform(MockMvcRequestBuilders.get("/employees"))
.andExpect(status().is2xxSuccessful())
.andExpect(MockMvcResultMatchers.jsonPath("$..employeeList[0].firstName").value("Max"));
}

最新更新