Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MockMvc Kotlin DSL should support async dispatch #23758

Closed
jnizet opened this issue Oct 4, 2019 · 1 comment
Closed

MockMvc Kotlin DSL should support async dispatch #23758

jnizet opened this issue Oct 4, 2019 · 1 comment
Assignees
Milestone

Comments

@jnizet
Copy link

@jnizet jnizet commented Oct 4, 2019

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 }
        }
@sdeleuze

This comment has been minimized.

Copy link
Contributor

@sdeleuze sdeleuze commented Nov 22, 2019

This is now supported via:

mockMvc.get("/async").asyncDispatch().andExpect {
	status { isOk }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
5 participants
You can’t perform that action at this time.