스웨거 테스트를 진행하면서 mutlipart formdata를 사용할 때 사진 파일과 json파일은 동시에 보내는 경우를 어떻게 테스트하는지 알아봤습니다.
1. 포스트맨
포스트맨 에서 테스트 하는 경우는 Formdata와 함께 json 파일을 보내는 경우 content type을 지정해서 전송할 수 있습니다.
아래와 같이 전송됩니다.
2.swagger
해당 부분을 swagger로 해결하는 방법은 두 가지가 있습니다.
1. file로 받는 방법
@Operation(summary = "피드 작성")
@PostMapping(consumes = {MediaType.MULTIPART_FORM_DATA_VALUE, MediaType.APPLICATION_JSON_VALUE})
public ApiResponse<PostResponseDto> savePostWithImage(
@Valid @RequestPart(value = "postRequestDto") @Parameter(schema = @Schema(type = "string", format = ("binary"))) PostRequestDto postRequestDto,
@RequestPart(name = "files", required = false) @Parameter(description = "포스트 이미지") List<MultipartFile> files,
@RequestPart(name = "file", required = false) @Parameter(description = "포스트 썸네일 이미지 등록하지 않는 경우 자동으로 처음이미지 설정") MultipartFile file
) {
PostResponseDto postResponseDto = postService.saveWithImages(postRequestDto, files, file, getCurrentUsername());
return ApiResponse.success(postResponseDto);
}
위에 처럼 코드를 작성하여 json부분을 파일로 넣는 방법입니다.
위와 같이 전송하면 아래와 같이 잘 전송된것을 확인할 수 있습니다.
2. 처리하는 bean 을 추가하는 방법(octetstream 허용)
SwaggerBeanConfig를 추가합니다.
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import java.util.ArrayList;
@Configuration
public class SwaggerBeanConfig {
public SwaggerBeanConfig(MappingJackson2HttpMessageConverter converter) {
var supportedMediaTypes = new ArrayList<>(converter.getSupportedMediaTypes());
supportedMediaTypes.add(new MediaType("application", "octet-stream"));
converter.setSupportedMediaTypes(supportedMediaTypes);
}
}
json으로 전송하지 않는 경우 아래와 같은 오류가 발생하는데 octet-stream을 받을 수 있도록 해줍니다.
Resolved [org.springframework.web.HttpMediaTypeNotSupportedException: Content-Type 'application/octet-stream' is not supported]
이후에 컨트롤러에서는 동일하게 @RequestPart를 이용하여 입력을 받습니다.
@Operation(summary = "피드 작성")
@PostMapping(consumes = {MediaType.MULTIPART_FORM_DATA_VALUE, MediaType.APPLICATION_JSON_VALUE})
public ApiResponse<PostResponseDto> savePostWithImage(
@Valid @RequestPart(name="postRequestDto") PostRequestDto postRequestDto,
@RequestPart(name = "files", required = false) @Parameter(description = "포스트 이미지") List<MultipartFile> files,
@RequestPart(name = "file", required = false) @Parameter(description = "포스트 썸네일 이미지 등록하지 않는 경우 자동으로 처음이미지 설정") MultipartFile file
) {
PostResponseDto postResponseDto = postService.saveWithImages(postRequestDto, files, file, getCurrentUsername());
return ApiResponse.success(postResponseDto);
}
위와 모두 requestPart로 입력을 동일하게 받습니다.
위와 같이 잘 입력받아 저장되는것을 확인할 수 있습니다.
3. test코드
또한 참고로 만약 테스트 코드를 작성하는 경우라면 위와 같은 예제는 아니지만 아래와 같이 오브젝트를 json파일로 변환해서 보내줄 수 있습니다.
@Test
@DisplayName("item 생성 조회 (POST /items)")
public void saveItem() throws Exception {
//given
RequestSalesItemDto dto = getRequestSalesItemDto();
String requestSalesItemDto = new ObjectMapper().writeValueAsString(dto);
//when
//아래와 같이 json으로 변환해서 보내준다
MockMultipartFile jsonFile = new MockMultipartFile("requestSalesItemDto", "requestSalesItemDto", "application/json", requestSalesItemDto.getBytes(StandardCharsets.UTF_8));
mockMvc.perform(multipart("/items")
.file(jsonFile)
.header("Authorization", loginDto.getGrantType() + " " + loginDto.getAccessToken()))
.andExpectAll(
status().is2xxSuccessful(),
jsonPath("message").value(SAVE_ITEM_MESSAGE),
content().contentType(MediaType.APPLICATION_JSON)
);
//then
List<SalesItem> all = salesItemRepository.findAll();
SalesItem salesItem = all.get(0);
assertThat(salesItem.getTitle()).isEqualTo(dto.getTitle());
}
참고
https://swagger.io/docs/specification/describing-request-body/multipart-requests/
https://github.com/swagger-api/swagger-ui/issues/6462
https://github.com/swagger-api/swagger-ui/issues/5169
https://github.com/Morasiu/Swashbuckle.AspNetCore.JsonMultipartFormDataSupport
https://whatsmyinterest.tistory.com/76
https://stackoverflow.com/questions/16230291/requestpart-with-mixed-multipart-request-spring-mvc-3-2
https://github.com/springdoc/springdoc-openapi/issues/820
https://github.com/springdoc/springdoc-openapi/issues/833
https://github.com/springdoc/springdoc-openapi/issues/396
https://minholee93.tistory.com/entry/Spring-Json-with-MultipartFile
댓글