-
[스프링부트] 이미지 업로드 테스트 postman + restdocsBackEnd/SpringBoot 2023. 12. 3. 19:44
1. RequestPart
Content-Type이 multipart/form-data로 오는 요청에 대해 동작하며
MultipartResolver 를 통해서 multipartFile을 받을 수있고 동시에 HttpMessageConverter를 통해서 RequestBody도 수행함을 알 수있다.
공식문서 :
2. 테스트 대상 컨트롤러
multipartFile : thumbnailImg, roomImgList
requestbody : appRoomView
@LoginCompanyCheck @PostMapping("/create") public JsonResponse<AppRoomDTO> appCompanyCreate(@CurrentCompany LoginCompanyInfo loginCompanyInfo, @RequestPart(value = "appRoomView") AppRoomView appRoomView, @RequestPart(value = "thumbnailImg", required = false) MultipartFile thumbnailImg, @RequestPart(value = "roomImgList", required = false) List<MultipartFile> roomImgList) throws UserNotFoundException { AppRoomDTO appRoomDTO = appRoomService.companyRoomCreate(loginCompanyInfo, appRoomView, thumbnailImg, roomImgList); return JsonResponse.success(appRoomDTO); }
3. Postman
3.1 Body
json 객체의 경우 다음과같이 작성한다.
key : controller key와 동일하게 설정
value : json 필드 동일하게 설정
content-Type : application/json 입력
key : controller key와 동일하게 설정 ( file로 설정 )
value : selectFiles눌러서 선택 (List 타입인경우 여러개 클릭후 선택)
content-Type : multipart/form-data 입력
file 옆칸에 working directory 경고가 뜬다면 설정 -> Read files outside working directory를 On 해준다.
3.1 Header
header는 자동으로 body에 형식으로 잡히기 때문에 그대로 진행한다.
만약에 Content-Type에서 multipart/form-data;로 수정하는경우 boundary 에러가 발생한다.
boundary를 자동으로 계산할수있게 기본 설정으로 둔다.
4. Spring-rest-docs
MockMultiPartFile을 생성한다.
이미지 데이터
MockMultipartFile thumbNailImg = new MockMultipartFile("thumbNailImg", "image.png", MediaType.MULTIPART_FORM_DATA_VALUE, "example".getBytes());
Json 데이터
String requestJson = objectMapper.writeValueAsString( new AppRoomView( "roomNm", "comName", 1, LocalDateTime.now(), LocalDateTime.now(), "roomDesc", "Y", 5 ) ); MockMultipartFile requestBody = new MockMultipartFile("appRoomView", "", MediaType.APPLICATION_JSON_VALUE, requestJson.getBytes());
mockMvc
방금 생성한 mock파일을 넣어준다.
mockMvc.perform(multipart("/room/create").file(thumbNailImg).file(requestBody)
전체 코드
@Test @DisplayName("객실 정보 수정") @WithMockCustomUser public void roomModifyTest() throws Exception { // given String requestJson = objectMapper.writeValueAsString( new AppRoomView( "roomNm", "comName", 1, LocalDateTime.now(), LocalDateTime.now(), "roomDesc", "Y", 5 ) ); List<MockMultipartFile> roomPicList = new ArrayList<>(); for (int i = 0; i < 2; i++) { roomPicList.add(new MockMultipartFile("roomImgList", i + "image.png" , MediaType.MULTIPART_FORM_DATA_VALUE, "example".getBytes())); } MockMultipartFile thumbNailImg = new MockMultipartFile("thumbNailImg", "image.png", MediaType.MULTIPART_FORM_DATA_VALUE, "example".getBytes()); MockMultipartFile requestBody = new MockMultipartFile("appRoomView", "", MediaType.APPLICATION_JSON_VALUE, requestJson.getBytes()); given(appRoomService.companyRoomCreate( any(LoginCompanyInfo.class), any(AppRoomView.class), any(MultipartFile.class), any(List.class))) .willReturn( AppRoomDTO.builder() .id(1L) .comId(1L) .comName("toryCompany") .soldOutYn("N") .couponYn("Y") .thumbNail("defaultThumbNail") .roomDesc("roomDesc") .maxCount(1) .sellPrc(100000) .roomPicDTOList( List.of(AppRoomPicDTO.builder() .id(1L) .picLocation("UUID + pictureImgName") .picSeq(0) .modifiedDate(LocalDateTime.now()) .createdDate(LocalDateTime.now()) .build())) .modifiedDate(LocalDateTime.now()) .createdDate(LocalDateTime.now()) .build() ); // when mockMvc.perform(multipart("/room/create") .file(roomPicList.get(0)) .file(roomPicList.get(1)) .file(thumbNailImg) .file(requestBody) .cookie(new Cookie(CommonConstant.ACCOUNT_TOKEN.getName(), "jwtToken")) .contentType(MediaType.APPLICATION_JSON) .accept(MediaType.APPLICATION_JSON)) // then .andExpect(status().isOk()) .andDo(restDocs.document( requestCookies( cookieWithName(CommonConstant.ACCOUNT_TOKEN.getName()).description("JWT 토큰") ), requestParts( partWithName("thumbNailImg").description("객실 썸네일 파일").optional(), partWithName("roomImgList").description("객실 이미지 파일들").optional(), partWithName("appRoomView").description("객실 정보 수정") ), requestPartFields( "appRoomView", fieldWithPath("roomNm").type(JsonFieldType.STRING).description("객실 이름"), fieldWithPath("comName").type(JsonFieldType.STRING).description("회사 이름"), fieldWithPath("sellPrc").type(JsonFieldType.NUMBER).description("객실 가격"), fieldWithPath("checkIn").type(JsonFieldType.STRING).description("체크 인 시간"), fieldWithPath("checkOut").type(JsonFieldType.STRING).description("체크 아웃 시간"), fieldWithPath("roomDesc").type(JsonFieldType.STRING).description("객실 설명"), fieldWithPath("couponYn").type(JsonFieldType.STRING).description("쿠폰 사용 여부"), fieldWithPath("maxCount").type(JsonFieldType.NUMBER).description("총 객실 수") ), responseFields( fieldWithPath("message").type(JsonFieldType.STRING).description("메세지"), fieldWithPath("result").type(JsonFieldType.STRING).description("결과"), fieldWithPath("data").type(JsonFieldType.OBJECT).description("데이터"), fieldWithPath("data.id").type(JsonFieldType.NUMBER).description("객실 ID"), fieldWithPath("data.comId").type(JsonFieldType.NUMBER).description("기업 ID"), fieldWithPath("data.comName").type(JsonFieldType.STRING).description("기업 명"), fieldWithPath("data.soldOutYn").type(JsonFieldType.STRING).description("품절 여부"), fieldWithPath("data.thumbNail").type(JsonFieldType.STRING).description("객실 썸네일 이미지"), fieldWithPath("data.roomDesc").type(JsonFieldType.STRING).description("객실 설명"), fieldWithPath("data.maxCount").type(JsonFieldType.NUMBER).description("총 객실 수"), fieldWithPath("data.roomDesc").type(JsonFieldType.STRING).description("객실 설명"), fieldWithPath("data.sellPrc").type(JsonFieldType.NUMBER).description("객실 가격"), fieldWithPath("data.couponYn").type(JsonFieldType.STRING).description("쿠폰 사용 여부"), fieldWithPath("data.roomPicDTOList").type(JsonFieldType.ARRAY).description("객실 사진 정보"), fieldWithPath("data.roomPicDTOList[].id").type(JsonFieldType.NUMBER).description("객실 사진 ID"), fieldWithPath("data.roomPicDTOList[].picLocation").type(JsonFieldType.STRING).description("객실 사진 위치 명"), fieldWithPath("data.roomPicDTOList[].picSeq").type(JsonFieldType.NUMBER).description("객실 사진 순서"), fieldWithPath("data.roomPicDTOList[].modifiedDate").type(JsonFieldType.STRING).description("객실 사진 생성 일시"), fieldWithPath("data.roomPicDTOList[].createdDate").type(JsonFieldType.STRING).description("객실 사진 수정 일시"), fieldWithPath("data.modifiedDate").type(JsonFieldType.STRING).description("객실 생성 일시"), fieldWithPath("data.createdDate").type(JsonFieldType.STRING).description("객실 수정 일시") )) ); }
완성된 request 필드
'BackEnd > SpringBoot' 카테고리의 다른 글
[스프링부트] @DataJpaTest 멀티스레드에서 no value present (1) 2023.12.06 [스프링부트] 테스트 시 Mysql관련 에러 Unique index or primary key violation (0) 2023.11.24 [스프링부트] ./gradlew build시 에러 -> error: cannot find symbol (0) 2023.11.16 토비의 스프링 - 1권 6장 AOP (0) 2023.10.08