Add body methods with Object parameter to WebFlux
The commit deprecates syncBody(Object) in favor of body(Object) which has the same behavior in ServerResponse, WebClient and WebTestClient. It also adds body(Object, Class) and body(Object, ParameterizedTypeReference) methods in order to support any reactive type that can be adapted to a Publisher via ReactiveAdapterRegistry. Related BodyInserters#fromProducer methods are provided as well. Shadowed Kotlin body<T>() extensions are deprecated in favor of bodyWithType<T>() ones, including dedicated Publisher<T> and Flow<T> variants. Coroutines extensions are adapted as well, and body(Object) can now be used with suspending functions. Closes gh-23212
This commit is contained in:
@@ -61,7 +61,7 @@ public class ApplicationContextSpecTests {
|
||||
.GET("/sessionClassName", request ->
|
||||
request.session().flatMap(session -> {
|
||||
String className = session.getClass().getSimpleName();
|
||||
return ServerResponse.ok().syncBody(className);
|
||||
return ServerResponse.ok().body(className);
|
||||
}))
|
||||
.build();
|
||||
}
|
||||
|
||||
@@ -63,7 +63,7 @@ public class ErrorTests {
|
||||
EntityExchangeResult<Void> result = this.client.post()
|
||||
.uri("/post")
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.syncBody(new Person("Dan"))
|
||||
.body(new Person("Dan"))
|
||||
.exchange()
|
||||
.expectStatus().isBadRequest()
|
||||
.expectBody().isEmpty();
|
||||
|
||||
@@ -82,7 +82,7 @@ public class JsonContentTests {
|
||||
public void postJsonContent() {
|
||||
this.client.post().uri("/persons")
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.syncBody("{\"name\":\"John\"}")
|
||||
.body("{\"name\":\"John\"}")
|
||||
.exchange()
|
||||
.expectStatus().isCreated()
|
||||
.expectBody().isEmpty();
|
||||
|
||||
@@ -145,7 +145,7 @@ public class ResponseEntityTests {
|
||||
@Test
|
||||
public void postEntity() {
|
||||
this.client.post()
|
||||
.syncBody(new Person("John"))
|
||||
.body(new Person("John"))
|
||||
.exchange()
|
||||
.expectStatus().isCreated()
|
||||
.expectHeader().valueEquals("location", "/persons/John")
|
||||
|
||||
@@ -116,7 +116,7 @@ public class XmlContentTests {
|
||||
|
||||
this.client.post().uri("/persons")
|
||||
.contentType(MediaType.APPLICATION_XML)
|
||||
.syncBody(content)
|
||||
.body(content)
|
||||
.exchange()
|
||||
.expectStatus().isCreated()
|
||||
.expectHeader().valueEquals(HttpHeaders.LOCATION, "/persons/John")
|
||||
|
||||
@@ -45,7 +45,7 @@ public class HttpServerTests {
|
||||
@Before
|
||||
public void start() throws Exception {
|
||||
HttpHandler httpHandler = RouterFunctions.toHttpHandler(
|
||||
route(GET("/test"), request -> ServerResponse.ok().syncBody("It works!")));
|
||||
route(GET("/test"), request -> ServerResponse.ok().body("It works!")));
|
||||
|
||||
this.server = new ReactorHttpServer();
|
||||
this.server.setHandler(httpHandler);
|
||||
|
||||
@@ -41,7 +41,7 @@ public class RouterFunctionTests {
|
||||
public void setUp() throws Exception {
|
||||
|
||||
RouterFunction<?> route = route(GET("/test"), request ->
|
||||
ServerResponse.ok().syncBody("It works!"));
|
||||
ServerResponse.ok().body("It works!"));
|
||||
|
||||
this.testClient = WebTestClient.bindToRouterFunction(route).build();
|
||||
}
|
||||
|
||||
@@ -18,10 +18,14 @@ package org.springframework.test.web.reactive.server
|
||||
|
||||
import io.mockk.mockk
|
||||
import io.mockk.verify
|
||||
import kotlinx.coroutines.FlowPreview
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Test
|
||||
import org.reactivestreams.Publisher
|
||||
import org.springframework.core.ParameterizedTypeReference
|
||||
import org.springframework.web.reactive.function.server.router
|
||||
import java.util.concurrent.CompletableFuture
|
||||
|
||||
/**
|
||||
* Mock object based tests for [WebTestClient] Kotlin extensions
|
||||
@@ -30,16 +34,31 @@ import org.springframework.web.reactive.function.server.router
|
||||
*/
|
||||
class WebTestClientExtensionsTests {
|
||||
|
||||
val requestBodySpec = mockk<WebTestClient.RequestBodySpec>(relaxed = true)
|
||||
private val requestBodySpec = mockk<WebTestClient.RequestBodySpec>(relaxed = true)
|
||||
|
||||
val responseSpec = mockk<WebTestClient.ResponseSpec>(relaxed = true)
|
||||
private val responseSpec = mockk<WebTestClient.ResponseSpec>(relaxed = true)
|
||||
|
||||
|
||||
@Test
|
||||
fun `RequestBodySpec#body with Publisher and reified type parameters`() {
|
||||
fun `RequestBodySpec#bodyWithType with Publisher and reified type parameters`() {
|
||||
val body = mockk<Publisher<Foo>>()
|
||||
requestBodySpec.body(body)
|
||||
verify { requestBodySpec.body(body, Foo::class.java) }
|
||||
requestBodySpec.bodyWithType(body)
|
||||
verify { requestBodySpec.body(body, object : ParameterizedTypeReference<Foo>() {}) }
|
||||
}
|
||||
|
||||
@Test
|
||||
@FlowPreview
|
||||
fun `RequestBodySpec#bodyWithType with Flow and reified type parameters`() {
|
||||
val body = mockk<Flow<Foo>>()
|
||||
requestBodySpec.bodyWithType(body)
|
||||
verify { requestBodySpec.body(body, object : ParameterizedTypeReference<Foo>() {}) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `RequestBodySpec#bodyWithType with CompletableFuture and reified type parameters`() {
|
||||
val body = mockk<CompletableFuture<Foo>>()
|
||||
requestBodySpec.bodyWithType<Foo>(body)
|
||||
verify { requestBodySpec.body(body, object : ParameterizedTypeReference<Foo>() {}) }
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -51,7 +70,7 @@ class WebTestClientExtensionsTests {
|
||||
@Test
|
||||
fun `KotlinBodySpec#isEqualTo`() {
|
||||
WebTestClient
|
||||
.bindToRouterFunction( router { GET("/") { ok().syncBody("foo") } } )
|
||||
.bindToRouterFunction( router { GET("/") { ok().body("foo") } } )
|
||||
.build()
|
||||
.get().uri("/").exchange().expectBody<String>().isEqualTo("foo")
|
||||
}
|
||||
@@ -59,7 +78,7 @@ class WebTestClientExtensionsTests {
|
||||
@Test
|
||||
fun `KotlinBodySpec#consumeWith`() {
|
||||
WebTestClient
|
||||
.bindToRouterFunction( router { GET("/") { ok().syncBody("foo") } } )
|
||||
.bindToRouterFunction( router { GET("/") { ok().body("foo") } } )
|
||||
.build()
|
||||
.get().uri("/").exchange().expectBody<String>().consumeWith { assertEquals("foo", it.responseBody) }
|
||||
}
|
||||
@@ -67,7 +86,7 @@ class WebTestClientExtensionsTests {
|
||||
@Test
|
||||
fun `KotlinBodySpec#returnResult`() {
|
||||
WebTestClient
|
||||
.bindToRouterFunction( router { GET("/") { ok().syncBody("foo") } } )
|
||||
.bindToRouterFunction( router { GET("/") { ok().body("foo") } } )
|
||||
.build()
|
||||
.get().uri("/").exchange().expectBody<String>().returnResult().apply { assertEquals("foo", responseBody) }
|
||||
}
|
||||
@@ -75,13 +94,13 @@ class WebTestClientExtensionsTests {
|
||||
@Test
|
||||
fun `ResponseSpec#expectBodyList with reified type parameters`() {
|
||||
responseSpec.expectBodyList<Foo>()
|
||||
verify { responseSpec.expectBodyList(Foo::class.java) }
|
||||
verify { responseSpec.expectBodyList(object : ParameterizedTypeReference<Foo>() {}) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `ResponseSpec#returnResult with reified type parameters`() {
|
||||
responseSpec.returnResult<Foo>()
|
||||
verify { responseSpec.returnResult(Foo::class.java) }
|
||||
verify { responseSpec.returnResult(object : ParameterizedTypeReference<Foo>() {}) }
|
||||
}
|
||||
|
||||
class Foo
|
||||
|
||||
Reference in New Issue
Block a user