Spring 使用 Map 参数在控制器上启动补丁请求。用 mockmvc 测试
Spring boot patch request on controller with Map parameter. Test with mockmvc
我正在尝试从我的 CompanyController 中测试一个 'patch request',它有一个 Map 和 Id 作为参数。我希望得到一个 HTTP 状态 200,但我得到一个 HTTP 状态 400。
有人可以向我解释我做错了什么吗?谢谢
CompanyController(部分代码省略):
@RestController
public class CompanyController {
@Autowired
private CompanyService companyService;
@PatchMapping("companies/{id}")
public ResponseEntity<CompanyDTO> patchUpdateCompany(@PathVariable Integer id,
@RequestBody Map<String, Object> updates) throws JsonMappingException {
Optional<CompanyDTO> optionalCompanyDTO = this.companyService.patchUpdateCompany(updates, id);
return ResponseEntity.ok(optionalCompanyDTO.get());
}
}
CompanyControllerTest(部分代码省略)
@WebMvcTest(CompanyController.class)
public class CompanyControllerTest {
@MockBean
private CompanyService companyService;
@Autowired
private MockMvc mockMvc;
private static List<CompanyDTO> companyDTOList;
@BeforeAll
public static void beforeAll(){
companyDTOList = new ArrayList<>();
CompanyDTO companyDTO1 = CompanyDTO.builder().id(1).name("xavi").build();
CompanyDTO companyDTO2 = CompanyDTO.builder().id(2).name("marteta").build();
companyDTOList.add(companyDTO1);
companyDTOList.add(companyDTO2);
}
@Test
void givenMapAndIdWhenPatchUpdateCompanyThenReturnHttpStatusOk() throws Exception {
Mockito.when(this.companyService.getCompanyById(1)).thenReturn(Optional.of(companyDTOList.get(0)));
MultiValueMap<String, String> parameters = new LinkedMultiValueMap<>();
parameters.add("name", "xavi2");
this.mockMvc.perform(patch("/companies/1")
.contentType(MediaType.APPLICATION_JSON)
.params(requestParams))
.andExpect(status().isOk())
.andExpect(jsonPath("$.name", Matchers.is("xavi2")));
}
}
你的问题就在这里
this.mockMvc.perform(patch("/companies/1")
.contentType(MediaType.APPLICATION_JSON)
.params(requestParams)) <---------------------
.andExpect(status().isOk())
.andExpect(jsonPath("$.name", Matchers.is("xavi2")));
}
您将数据作为请求参数传递。但是在你的 API 中你有 @RequestBody
意味着它希望在 http 请求正文中获取数据而不是作为请求参数。
这就是为什么您会遇到 400
错误,意思是 Bad Request
,这是由 Spring 匹配 URL 路径和 http 方法类型引起的,但还有一些额外的东西在您的请求中未提供 API 方法的签名中。
所以你应该使用.content(requestParams)
方法在你要发送的请求正文中设置你想要的内容
否则,您的 API 应该使用 @RequestParam
而不是 @RequestBody
来接收先前从测试发送的请求参数输入。
我正在尝试从我的 CompanyController 中测试一个 'patch request',它有一个 Map 和 Id 作为参数。我希望得到一个 HTTP 状态 200,但我得到一个 HTTP 状态 400。 有人可以向我解释我做错了什么吗?谢谢
CompanyController(部分代码省略):
@RestController
public class CompanyController {
@Autowired
private CompanyService companyService;
@PatchMapping("companies/{id}")
public ResponseEntity<CompanyDTO> patchUpdateCompany(@PathVariable Integer id,
@RequestBody Map<String, Object> updates) throws JsonMappingException {
Optional<CompanyDTO> optionalCompanyDTO = this.companyService.patchUpdateCompany(updates, id);
return ResponseEntity.ok(optionalCompanyDTO.get());
}
}
CompanyControllerTest(部分代码省略)
@WebMvcTest(CompanyController.class)
public class CompanyControllerTest {
@MockBean
private CompanyService companyService;
@Autowired
private MockMvc mockMvc;
private static List<CompanyDTO> companyDTOList;
@BeforeAll
public static void beforeAll(){
companyDTOList = new ArrayList<>();
CompanyDTO companyDTO1 = CompanyDTO.builder().id(1).name("xavi").build();
CompanyDTO companyDTO2 = CompanyDTO.builder().id(2).name("marteta").build();
companyDTOList.add(companyDTO1);
companyDTOList.add(companyDTO2);
}
@Test
void givenMapAndIdWhenPatchUpdateCompanyThenReturnHttpStatusOk() throws Exception {
Mockito.when(this.companyService.getCompanyById(1)).thenReturn(Optional.of(companyDTOList.get(0)));
MultiValueMap<String, String> parameters = new LinkedMultiValueMap<>();
parameters.add("name", "xavi2");
this.mockMvc.perform(patch("/companies/1")
.contentType(MediaType.APPLICATION_JSON)
.params(requestParams))
.andExpect(status().isOk())
.andExpect(jsonPath("$.name", Matchers.is("xavi2")));
}
}
你的问题就在这里
this.mockMvc.perform(patch("/companies/1")
.contentType(MediaType.APPLICATION_JSON)
.params(requestParams)) <---------------------
.andExpect(status().isOk())
.andExpect(jsonPath("$.name", Matchers.is("xavi2")));
}
您将数据作为请求参数传递。但是在你的 API 中你有 @RequestBody
意味着它希望在 http 请求正文中获取数据而不是作为请求参数。
这就是为什么您会遇到 400
错误,意思是 Bad Request
,这是由 Spring 匹配 URL 路径和 http 方法类型引起的,但还有一些额外的东西在您的请求中未提供 API 方法的签名中。
所以你应该使用.content(requestParams)
方法在你要发送的请求正文中设置你想要的内容
否则,您的 API 应该使用 @RequestParam
而不是 @RequestBody
来接收先前从测试发送的请求参数输入。