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

Want to add MockMvc DSL extension #293

Open
christian-draeger opened this issue Jun 19, 2023 · 0 comments
Open

Want to add MockMvc DSL extension #293

christian-draeger opened this issue Jun 19, 2023 · 0 comments

Comments

@christian-draeger
Copy link
Contributor

christian-draeger commented Jun 19, 2023

I am using spring-boot projects a lot.
All my tests using strikt as an assertions library already.

To test my rest controllers i mostly use mockMvc among my projects. but since assertions on mockMvc result body require to use hamcrest matchers it needs extra knowledge (aka learn a second assertion lib and its matchers). also the hamcrest matchers are not nice to use or type-safe.

since i know the expected result types of my controllers (which are part of my project anyway) i wrote a little extension to be able to deserialize the response body and use strikt matchers directly to assert body.
i think this is a pretty common use-case.

i would like to add it upstream, but am unsure if it could be part of the strikt-spring extension or if it should be another (strikt-mockmvc) extension.

😢 what it looks like with vanilla mock mvc DSL (using hamcrest, not typesafe):

    @Test
    internal fun `example mockMvc test`() {
        mockMvc.get("http://localhost:$port/foo")
            .andExpect {
                status { isOk() }
                content {
                    jsonPath("$[0].title", Matchers.equalTo("foo"))
                    jsonPath("$.size()", Matchers.equalTo(2))
                }
            }
    }

🚸 what it looks like working around it to use strikt:

    @Test
    internal fun `example mockMvc test using strikt`() {
        mockMvc.get("http://localhost:$port/foo")
            .andExpect {
                status { isOk() }
            }.andDeserializeBody<List<ResultDto>>()

        expectThat(resultBody) {
            get { first().title }.isEqualTo("foo")
            hasSize(2)
        }
    }

    inline fun <reified T> ResultActionsDsl.andDeserializeBody(mapper: ObjectMapper = jacksonObjectMapper()): T =
    andReturn().response.contentAsString.let(mapper::readValue)

😎 what it looks like with fancy extension:

    @Test
    internal fun `example mockMvc test using strikt mockmvc extension`() {
        mockMvc.get("http://localhost:$port/foo")
            .andExpect {
                status { isOk() }
            }.andExpectBody<List<ResultDto>> {
                get { first().title }.isEqualTo("foo")
                hasSize(2)
            }
    }
    
    // what would basically be added to strikt as an extension to make the syntax above possible:
    inline fun <reified T> ResultActionsDsl.andDeserializeBody(mapper: ObjectMapper = jacksonObjectMapper()): T =
    andReturn().response.contentAsString.let(mapper::readValue)

    inline fun <reified T> ResultActionsDsl.andExpectBody(crossinline block: Assertion.Builder<T>.() -> Unit): ResultActionsDsl =
        also {
            andDeserializeBody<T>().run {
                expectThat(this) {
                    block()
                }
            }
        }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant