Skip to content

MockMvc Kotlin DSL should support async dispatch #23758

@jnizet

Description

@jnizet

Affects: 5.2.0.RELEASE

Spring MVC now supports returning a Mono from REST controller handler methods. And this, in my experience, becomes more and more common because the reactive WebClient tends to be used instead of RestTemplate in MVC applications.

Testing those handler methods with MockMvc requires doing an async dispatch, as documented here.

This is not easy to find out with the MockMvc Java DSL. But when using MockMvc Kotlin DSL, it's even less intuitive. Here's the required code (AFAIK):

        val mvcResult =
            mockMvc.get(url).andExpect {
                request { asyncStarted() }
            }.andReturn()

        ResultActionsDsl(mockMvc.perform(MockMvcRequestBuilders.asyncDispatch(mvcResult))).andExpect {
            status { isOk }
        }

As you can see, it requires:

  • using the static method MockMvcRequestBuilders.asyncDispatch(), whereas the Kotlin DSL is designed to avoid having to use static methods, which are hard to find
  • making two subsequent calls to mockMvc, which is unintuitive
  • calling mockMvc.perform(), although the Kotlin DSL usually avoids it thanks to its extension methods (get(), post(), etc.)
  • creating a new instance of the ResultActionsDsl class explicitly, which is also unintuitive.

I can hide this complexity into an extension function, but I think this function shouldn't be required, and should be part of the DSL itself:

fun ResultActionsDsl.asyncDispatch(mockMvc: MockMvc): ResultActionsDsl {
    return this.andExpect {
        request { asyncStarted() }
    }.andReturn().let {
        ResultActionsDsl(mockMvc.perform(MockMvcRequestBuilders.asyncDispatch(it)))
    }
}

This allows using the following code to write the same test as above:

        mockMvc.get(url).asyncDispatch(mockMvc).andExpect {
            status { isOk }
        }

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions