From 212326a754c4f9849bb6ed114b5d70c1df84fe4d Mon Sep 17 00:00:00 2001 From: Denis Zhdanov Date: Sun, 23 Jun 2019 13:50:50 +0800 Subject: [PATCH] BAEL-2910 MockMvc Kotlin DSL * configured spring repo in the 'parent-kotlin' model to allow using spring's milestone artifacts * configured jackson kotlin module in the 'parent-kotlin' to allow easy use of kotlin data classes with jackson * switched spring-mvc-kotlin from explicit spring dependencies to spring-boot * mockmvc dsl article's source and tests --- parent-kotlin/pom.xml | 11 +++- spring-mvc-kotlin/pom.xml | 12 ++-- .../kotlin/mockmvc/MockMvcController.kt | 26 ++++++++ .../baeldung/kotlin/mockmvc/MockMvcModel.kt | 10 +++ .../kotlin/mockmvc/MockMvcControllerTest.kt | 61 +++++++++++++++++++ 5 files changed, 113 insertions(+), 7 deletions(-) create mode 100644 spring-mvc-kotlin/src/main/kotlin/com/baeldung/kotlin/mockmvc/MockMvcController.kt create mode 100644 spring-mvc-kotlin/src/main/kotlin/com/baeldung/kotlin/mockmvc/MockMvcModel.kt create mode 100644 spring-mvc-kotlin/src/test/kotlin/com/baeldung/kotlin/mockmvc/MockMvcControllerTest.kt diff --git a/parent-kotlin/pom.xml b/parent-kotlin/pom.xml index 6f7fe6c102..d993fad3c6 100644 --- a/parent-kotlin/pom.xml +++ b/parent-kotlin/pom.xml @@ -26,6 +26,11 @@ kotlin-eap http://dl.bintray.com/kotlin/kotlin-eap + + spring-milestone + Spring Milestone Repository + http://repo.spring.io/milestone + @@ -40,7 +45,7 @@ org.springframework.boot spring-boot-dependencies - 2.0.1.RELEASE + 2.2.0.M4 pom import @@ -80,6 +85,10 @@ ktor-gson ${ktor.io.version} + + com.fasterxml.jackson.module + jackson-module-kotlin + org.jetbrains.kotlin diff --git a/spring-mvc-kotlin/pom.xml b/spring-mvc-kotlin/pom.xml index fc76f58727..fb1f242644 100644 --- a/spring-mvc-kotlin/pom.xml +++ b/spring-mvc-kotlin/pom.xml @@ -15,12 +15,12 @@ - org.springframework - spring-web + org.springframework.boot + spring-boot-starter-web - org.springframework - spring-webmvc + org.springframework.boot + spring-boot-starter-json org.thymeleaf @@ -46,8 +46,8 @@ test - org.springframework - spring-test + org.springframework.boot + spring-boot-starter-test test diff --git a/spring-mvc-kotlin/src/main/kotlin/com/baeldung/kotlin/mockmvc/MockMvcController.kt b/spring-mvc-kotlin/src/main/kotlin/com/baeldung/kotlin/mockmvc/MockMvcController.kt new file mode 100644 index 0000000000..68ab5f31a6 --- /dev/null +++ b/spring-mvc-kotlin/src/main/kotlin/com/baeldung/kotlin/mockmvc/MockMvcController.kt @@ -0,0 +1,26 @@ +package com.baeldung.kotlin.mockmvc + +import org.springframework.http.MediaType +import org.springframework.web.bind.annotation.RequestBody +import org.springframework.web.bind.annotation.RequestMapping +import org.springframework.web.bind.annotation.RequestMethod +import org.springframework.web.bind.annotation.RestController + +@RestController +@RequestMapping("/mockmvc") +class MockMvcController { + + @RequestMapping(value = ["/validate"], method = [RequestMethod.POST], produces = [MediaType.APPLICATION_JSON_VALUE]) + fun validate(@RequestBody request: Request): Response { + val error = if (request.name.first == "admin") { + null + } else { + ERROR + } + return Response(error) + } + + companion object { + const val ERROR = "invalid user" + } +} \ No newline at end of file diff --git a/spring-mvc-kotlin/src/main/kotlin/com/baeldung/kotlin/mockmvc/MockMvcModel.kt b/spring-mvc-kotlin/src/main/kotlin/com/baeldung/kotlin/mockmvc/MockMvcModel.kt new file mode 100644 index 0000000000..3231b6f186 --- /dev/null +++ b/spring-mvc-kotlin/src/main/kotlin/com/baeldung/kotlin/mockmvc/MockMvcModel.kt @@ -0,0 +1,10 @@ +package com.baeldung.kotlin.mockmvc + +import com.fasterxml.jackson.annotation.JsonInclude + +data class Name(val first: String, val last: String) + +data class Request(val name: Name) + +@JsonInclude(JsonInclude.Include.NON_NULL) +data class Response(val error: String?) \ No newline at end of file diff --git a/spring-mvc-kotlin/src/test/kotlin/com/baeldung/kotlin/mockmvc/MockMvcControllerTest.kt b/spring-mvc-kotlin/src/test/kotlin/com/baeldung/kotlin/mockmvc/MockMvcControllerTest.kt new file mode 100644 index 0000000000..802cd4c1e7 --- /dev/null +++ b/spring-mvc-kotlin/src/test/kotlin/com/baeldung/kotlin/mockmvc/MockMvcControllerTest.kt @@ -0,0 +1,61 @@ +package com.baeldung.kotlin.mockmvc + +import com.fasterxml.jackson.databind.ObjectMapper +import org.junit.Test +import org.junit.runner.RunWith +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.boot.autoconfigure.SpringBootApplication +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest +import org.springframework.http.MediaType +import org.springframework.http.ResponseEntity.status +import org.springframework.test.context.junit4.SpringRunner +import org.springframework.test.web.servlet.MockMvc +import org.springframework.test.web.servlet.post +import org.springframework.test.web.servlet.request.MockMvcRequestBuilders +import org.springframework.test.web.servlet.result.MockMvcResultHandlers +import org.springframework.test.web.servlet.result.MockMvcResultMatchers + +@RunWith(SpringRunner::class) +@WebMvcTest +class MockMvcControllerTest { + + @Autowired lateinit var mockMvc: MockMvc + @Autowired lateinit var mapper: ObjectMapper + + @Test + fun `when supported user is given then raw MockMvc-based validation is successful`() { + mockMvc.perform(MockMvcRequestBuilders + .post("/mockmvc/validate") + .accept(MediaType.APPLICATION_JSON) + .contentType(MediaType.APPLICATION_JSON) + .content(mapper.writeValueAsString(Request(Name("admin", ""))))) + .andExpect(MockMvcResultMatchers.status().isOk) + .andExpect(MockMvcResultMatchers.content().contentType(MediaType.APPLICATION_JSON)) + .andExpect(MockMvcResultMatchers.content().string("{}")) + } + + @Test + fun `when supported user is given then kotlin DSL-based validation is successful`() { + doTest(Request(Name("admin", "")), Response(null)) + } + + @Test + fun `when unsupported user is given then validation is failed`() { + doTest(Request(Name("some-name", "some-surname")), Response(MockMvcController.ERROR)) + } + + private fun doTest(input: Request, expectation: Response) { + mockMvc.post("/mockmvc/validate") { + contentType = MediaType.APPLICATION_JSON + content = mapper.writeValueAsString(input) + accept = MediaType.APPLICATION_JSON + }.andExpect { + status { isOk } + content { contentType(MediaType.APPLICATION_JSON) } + content { json(mapper.writeValueAsString(expectation)) } + } + } +} + +@SpringBootApplication +class MockMvcApplication \ No newline at end of file