spring-bootkotlinspring-mvcspring-boot-testmockmvc

How to use kotlin style in mockMvc?


I have classical style test with mockMvc and it works:

    val result = mockMvc.perform(
        post(path)
            .contentType(MediaType.APPLICATION_JSON)
            .content(objectMapper.writeValueAsString(groupCreateDto)),
    ).andExpect(status().isBadRequest)
        .andReturn()    

I've met here that Kotlin has a specific style and I've decide to rewrite:

val result = mockMvc.post(path) {
    contentType = MediaType.APPLICATION_JSON
    content = content().string(objectMapper.writeValueAsString(groupCreateDto))
}.andExpect { status{isBadRequest()} }
    .andReturn()

But it doesn't work with error:

2023-10-03T13:19:34.536+03:00 ERROR 17912 --- [    Test worker] ***.RestExceptionHandler   : JSON parse error: Unrecognized token 'org': was expecting (JSON String, Number, Array, Object or token 'null', 'true' or 'false')

MockHttpServletRequest:
      HTTP Method = POST
      Request URI = /api/v1/groups
       Parameters = {}
          Headers = [Content-Type:"application/json", Content-Length:"106"]
             Body = <no character encoding set>
    Session Attrs = {}

Handler:
             Type = ****.MyGroupController
           Method = ****.MyGroupController#createGroup(GroupCreateRequestDto)

Async:
    Async started = false
     Async result = null

Resolved Exception:
             Type = org.springframework.http.converter.HttpMessageNotReadableException

ModelAndView:
        View name = null
             View = null
            Model = null

FlashMap:
       Attributes = null

MockHttpServletResponse:
           Status = 500
    Error message = null
          Headers = [Content-Type:"application/json"]
     Content type = application/json
             Body = {"code":500,"reason":"JSON parse error: Unrecognized token 'org': was expecting (JSON String, Number, Array, Object or token 'null', 'true' or 'false')"}
    Forwarded URL = null
   Redirected URL = null
          Cookies = []

BRW I don't have org in a string generated by objectMapper.writeValueAsString(groupCreateDto) Any ideas ?


Solution

  • The problem is caused by this line in the Kotlin translation:

    content = content().string(objectMapper.writeValueAsString(groupCreateDto))
    

    It should be just

    content = objectMapper.writeValueAsString(groupCreateDto)
    

    The latter code would reflect the same line from the original code. On the other hand, the content().string... construct creates a RequestMatcher, which is not what you want as you're not in the asserting part of the code at this point.