ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • MultipartFile 컨트롤러 단위 테스트(MockMvc)
    프로젝트/미디어 스트리밍 서버 프로젝트 2022. 8. 24. 01:03
    728x90

    컨트롤러 메서드

     @PostMapping(consumes = [MediaType.APPLICATION_JSON_VALUE, MediaType.MULTIPART_FORM_DATA_VALUE])
        fun fileUpload(
            @RequestPart request: UploadRequest,
            @RequestPart file: MultipartFile
        ): ResponseEntity<BasicResponse<UploadResponse>> {
            // todo : videoService 에서 upload 이후 반환되는 아이디 및 등록 과정 필요
            metadataService.registerMetadata(file)
            val uploadResponse = videoService.upload(request, file)
            return ResponseEntity(
                BasicResponse(SUCCESS, uploadResponse),
                HttpStatus.CREATED,
            )
        }

     

    @RequestPart을 통해서 request라는 변수명의 UploadRequest라는 json 요청을 받고 있습니다.

    @RequestPart를 통해서 file이라는 변수명의 MultipartFile 요청을 받고 있습니다.

     

    UploadRequest

    data class UploadRequest(
        val subject: String,
        val content: String,
    )

     

    BasicResponse

    data class BasicResponse<Type>(
        val message: String,
        val data: Type? = null,
    )

     

     

    컨트롤러 테스트 코드

    @WebMvcTest(VideoController::class)
    class VideoControllerTest(@Autowired val mockMvc: MockMvc) {
        @MockkBean
        lateinit var videoService: VideoService
    
        @MockkBean
        lateinit var metadataService: MetadataService
    
        @Test
        fun fileUpload() {
            // given
            every { metadataService.registerMetadata(any()) } just Runs
            every { videoService.upload(any(), any()) } returns UploadResponse("uploadUrl")
    
            val video = MockMultipartFile(
                "file",
                "video.mp4",
                "mp4",
                "videos".toByteArray(),
            )
            val uploadRequest = ObjectMapper().writeValueAsString(
                UploadRequest(
                    "subject",
                    "content",
                )
            )
            val json = MockMultipartFile(
                "request",
                "request",
                "application/json",
                uploadRequest.toByteArray(StandardCharsets.UTF_8),
            )
    
            // when
            val perform = mockMvc.perform(
                MockMvcRequestBuilders
                    .multipart("/video")
                    .file(video)
                    .file(json)
                    .contentType(MediaType.MULTIPART_FORM_DATA)
                    .accept(MediaType.APPLICATION_JSON)
                    .characterEncoding("UTF-8")
            )
    
            // then
            perform
                .andExpect(MockMvcResultMatchers.status().isCreated)
                .andExpect(jsonPath("$.data.url").value("uploadUrl"))
        }
    
    }

    1. Controller 단위 테스트이기 때문에 videoService와 metadataService는 @MockkBean처리를 해줍니다.

     

    2. Mocking한 메서드가 해야 하는 행위를 지정합니다.

     

    3. 이후 MultipartFile으로 넣어줄 video 파일과 json파일을 넣어줍니다. (이때 file, request의 이름을 컨트롤러에서 받는 이름과 일치시켜주어야 합니다.)

     

    4. multipart(url).file 메서드를 통해서 video와 json객체를 테스트에 넣어줍니다.

     

    5. jsonPath를 활용하여 data.url의 값이 uploadUrl임을 검증합니다.

     

     

     

    댓글

Designed by Tistory.