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

Fix expectations in MockMvc Kotlin documentation #28301

Closed
MrBuddyCasino opened this issue Apr 7, 2022 · 3 comments
Closed

Fix expectations in MockMvc Kotlin documentation #28301

MrBuddyCasino opened this issue Apr 7, 2022 · 3 comments
Assignees
Labels
theme: kotlin An issue related to Kotlin support type: documentation A documentation task
Milestone

Comments

@MrBuddyCasino
Copy link

This is a test against a generic PUT endpoint. The .andExpect { status().isOk } assertion always passes, regardless of the actual result status, while .andExpect( status().isOk ) works as expected. I suspect this is a bug?

We're using spring-boot-starter-parent:2.6.6 on Kotlin 1.6.10 on a JDK 11.

import org.junit.jupiter.api.Test
import org.junit.jupiter.api.TestInstance
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.http.MediaType.APPLICATION_JSON
import org.springframework.test.context.ActiveProfiles
import org.springframework.test.web.servlet.MockMvc
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders
import org.springframework.test.web.servlet.result.MockMvcResultMatchers.status

@SpringBootTest
@AutoConfigureMockMvc
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class Test {

    @Autowired
    lateinit var mockMvc: MockMvc

    @Test
    fun `should reject invalid payload`() {

        mockMvc.perform( MockMvcRequestBuilders.put("/analyses/297e2c6c6a26a2ba016a27bd5f977f74")
            .contentType(APPLICATION_JSON)
            .content("invalid")
        )
            .andExpect { status().isOk } // does not work
            .andExpect( status().isOk ) // works
    }
}
@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged or decided on label Apr 7, 2022
@bclozel bclozel transferred this issue from spring-projects/spring-boot Apr 7, 2022
@jnizet
Copy link

jnizet commented Apr 9, 2022

I can see how this is confusing, but I don't really see it as a bug.

andExpect() expects a ResultMatcher.
In the working case, that's what you're passing: status().isOk is an expression of type ResultMatcher. When it's match() method is called with an MvcResult, it checks that the status in the MvcResult is OK. So the working code is equivalent to

.andExpect { (mvcResult: MvcResult) ->
    status().isOk.match(mvcResult)
}

In the non-working case, you're passing { status().isOk }. This is a lambda which creates a ResultMatcher but never calls it. I.e. it's equivalent to

.andExpect { (mvcResult: MvcResult) ->
    val matcher: ResultMatcher = status().isOk 
    return Unit
}

Note how the mvcResult is never used anywhere in this lambda, and how the ResultMatcher it creates is never used either.

An alternative would be to use the MockMvc Kotlin DSL:

        mockMvc.put("/analyses/297e2c6c6a26a2ba016a27bd5f977f74") {
            contentType = APPLICATION_JSON
            content = "invalid"
        }.andExpect { status { isOk() } }

@MrBuddyCasino
Copy link
Author

MrBuddyCasino commented Apr 11, 2022

You're totally right, thanks for the detailed explanation! This is an example of the main failure mode of DSLs in my experience: what actually happens becomes more obfuscated in the quest for aesthetic call chains. Sorry to have wasted your time.

@kegt
Copy link

kegt commented Jul 5, 2022

So I think the official documents are being misleading here.

On https://docs.spring.io/spring-framework/docs/current/reference/html/testing.html#spring-mvc-test-server-defining-expectations you can see exactly the same code for kotlin.

@sdeleuze sdeleuze self-assigned this Jul 5, 2022
@sdeleuze sdeleuze added type: documentation A documentation task theme: kotlin An issue related to Kotlin support and removed status: waiting-for-triage An issue we've not yet triaged or decided on labels Jul 5, 2022
@sdeleuze sdeleuze added this to the 5.3.22 milestone Jul 5, 2022
@sdeleuze sdeleuze reopened this Jul 5, 2022
@sdeleuze sdeleuze changed the title MockMvc assertion silently ignored in Kotlin Fix expectations in MockMvc Kotlin documentation Jul 13, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
theme: kotlin An issue related to Kotlin support type: documentation A documentation task
Projects
None yet
Development

No branches or pull requests

5 participants