DolphaGo / TIL

TIL & issues
0 stars 1 forks source link

[SpringBoot] ControllerTest시 mockMvc에서 Pageable을 받을 수 없을 때 #113

Open DolphaGo opened 2 years ago

DolphaGo commented 2 years ago

Controller로 다음과 같은 api가 있다고 가정해보자.

  @GetMapping("/{id}/history")
  fun history(
      @PathVariable("id") id: Long,
      @PageableDefault pageable: Pageable
  ): Page<MyDto> = myService.getHistory(id, pageable)

만약 mockMvc를 다음과 같이 세팅을 했다고 가정해보자.

...

  @BeforeEach
  fun setup() {
      mockMvc = MockMvcBuilders.standaloneSetup(MyController).build()
      objectMapper = ObjectMapper().registerModule(JavaTimeModule())
          .disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
          .disable(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE)
  }

...

위 상태에서 다음과 같이 pageable을 테스트할 때 다음과 같은 에러를 마주할 것이다.

  val id = 1L
  val pageRequest : Pageable = PageRequest.of(1, 10)

  mockMvc.perform(
      MockMvcRequestBuilders.get("$URL/$id/history")
          .contentType(MediaType.APPLICATION_JSON)
          .content(objectMapper.writeValueAsString(pageRequest))
  ).andExpect(MockMvcResultMatchers.status().isOk)
      .andDo(print())
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is java.lang.IllegalStateException: No primary or single unique constructor found for interface org.springframework.data.domain.Pageable

이는 mockMvc에 argumentResolver를 하나 추가해주면 해결할 수 있다.

mockMvc = MockMvcBuilders.standaloneSetup(MyController)
    .setCustomArgumentResolvers(PageableHandlerMethodArgumentResolver())
    .build()