Controller
@PutMapping(value = "/modify", name = "자주묻는질문 > 수정") public BaseResponse<String> faqModify(@Valid @RequestPart FaqRegistRequest request, @RequestPart(required = false) List<MultipartFile> files) throws IOException, NoSuchAlgorithmException, InvalidKeyException { faqApplicationService.modifyFaqInfo(request, files); return BaseResponse.ofSuccess("자주묻는질문 수정 완료"); }
먼저 Controller 단을 보면 @RequestPart로 Request 객체와, MultipartFile들을 받고 있다.
이때 나는 수정 로직을 하고있었어서 @PutMapping 으로 지정해놨는데, 자꾸 맞지 않는 HttpMethod로 요청을 보냈을 때 발생하는 405 에러가 발생했다.
그냥 multipart()로 보내주고 있었는데, Multipart/form-data 요청은 default가 POST 였다.
따라서, 코드에서 HttpMethod 설정해줘야한다.
Test Controller
@Test void 자주묻는질문_수정() throws Exception { doNothing().when(faqApplicationService).modifyFaqInfo(any(FaqRegistRequest.class), anyList()); String accessToken = "access_token"; String result = "자주묻는질문 수정 완료"; List<Integer> deleteFaqImageIds = new ArrayList<>(); deleteFaqImageIds.add(1); deleteFaqImageIds.add(2); deleteFaqImageIds.add(5); FaqRegistRequest faqRequest = FaqRegistRequest.builder() .faqTitle("치실, 치간칫솔, 칫솔질 중 어떤 것을 먼저 해야 되나요?") .faqContent("순서는 상관 없고 선호하는대로 하면 됩니다.") .faqId(1) .deleteFaqImageIds(deleteFaqImageIds) .build(); MockMultipartFile file = new MockMultipartFile("files", "tooth.png", "multipart/form-data", "uploadFile".getBytes(StandardCharsets.UTF_8)); MockMultipartFile request = new MockMultipartFile("request", null, "application/json", objectMapper.writeValueAsString(faqRequest).getBytes(StandardCharsets.UTF_8)); mockMvc.perform( multipart("/faq/modify") .file(file) .file(request) .contentType(MediaType.MULTIPART_FORM_DATA) .accept(MediaType.APPLICATION_JSON) .header("Authorization", accessToken) ) .andExpect(status().isOk()) .andExpect(jsonPath("code").value(200)) .andExpect(jsonPath("message").value(SuccessMessage.SUCCESS_MSG)) .andExpect(jsonPath("data").value(result)) .andDo(document("faq/modify", getDocumentRequest(), getDocumentResponse(), requestParts( partWithName("request").description("요청값 Json"), partWithName("files").description("업로드 파일").optional() ), responseFields( fieldWithPath("code").type(JsonFieldType.NUMBER).description("결과 코드"), fieldWithPath("message").type(JsonFieldType.STRING).description("결과 메시지"), fieldWithPath("data").type(JsonFieldType.STRING).description("결과 데이터") ) )); verify(faqApplicationService).saveFaq(any(FaqRegistRequest.class), anyList()); }
Test Controller
@Test void 자주묻는질문_수정() throws Exception { doNothing().when(faqApplicationService).modifyFaqInfo(any(FaqRegistRequest.class), anyList()); String accessToken = "access_token"; String result = "자주묻는질문 수정 완료"; List<Integer> deleteFaqImageIds = new ArrayList<>(); deleteFaqImageIds.add(1); deleteFaqImageIds.add(2); deleteFaqImageIds.add(5); FaqRegistRequest faqRequest = FaqRegistRequest.builder() .faqTitle("치실, 치간칫솔, 칫솔질 중 어떤 것을 먼저 해야 되나요?") .faqContent("순서는 상관 없고 선호하는대로 하면 됩니다.") .faqId(1) .deleteFaqImageIds(deleteFaqImageIds) .build(); MockMultipartFile file = new MockMultipartFile("files", "tooth.png", "multipart/form-data", "uploadFile".getBytes(StandardCharsets.UTF_8)); MockMultipartFile request = new MockMultipartFile("request", null, "application/json", objectMapper.writeValueAsString(faqRequest).getBytes(StandardCharsets.UTF_8)); mockMvc.perform(MockMvcRequestBuilders //<------ 요기!!! .multipart(HttpMethod.PUT, "/faq/modify") //<-------- 요기!!! .file(file) .file(request) .accept(MediaType.APPLICATION_JSON) .contentType(MediaType.MULTIPART_FORM_DATA) .header("Authorization", accessToken) ) .andExpect(status().isOk()) .andExpect(jsonPath("code").value(200)) .andExpect(jsonPath("message").value(SuccessMessage.SUCCESS_MSG)) .andExpect(jsonPath("data").value(result)) .andDo(document("faq/modify", getDocumentRequest(), getDocumentResponse(), requestParts( partWithName("request").description("요청값 Json"), partWithName("files").description("업로드 파일").optional() ), responseFields( fieldWithPath("code").type(JsonFieldType.NUMBER).description("결과 코드"), fieldWithPath("message").type(JsonFieldType.STRING).description("결과 메시지"), fieldWithPath("data").type(JsonFieldType.STRING).description("결과 데이터") ) )); verify(faqApplicationService).modifyFaqInfo(any(FaqRegistRequest.class), anyList()); }
포인트는, MockMvcRequestBuilders
을 이용하여 Reuqest를 한번 빌드를 해줘야한다. 그러면 추가로 HttpMethod.PUT을 명시해줄 수 있다.