From 3373a3f7ef879f9c53085fc2cc1b61ec7cef910e Mon Sep 17 00:00:00 2001 From: Sebastien Deleuze Date: Mon, 12 Jun 2017 10:42:56 +0200 Subject: [PATCH] Add Kotlin extensions for WebTestClient API Issue: SPR-15622 --- build.gradle | 1 + .../web/reactive/server/WebTestClient.java | 2 +- .../server/WebTestClientExtensions.kt | 84 +++++++++++++++++++ .../server/WebTestClientExtensionsTests.kt | 74 ++++++++++++++++ 4 files changed, 160 insertions(+), 1 deletion(-) create mode 100644 spring-test/src/main/kotlin/org/springframework/test/web/reactive/server/WebTestClientExtensions.kt create mode 100644 spring-test/src/test/kotlin/org/springframework/test/web/reactive/server/WebTestClientExtensionsTests.kt diff --git a/build.gradle b/build.gradle index 6daa2ff3c4..42d0c78d2a 100644 --- a/build.gradle +++ b/build.gradle @@ -1039,6 +1039,7 @@ project("spring-test") { optional("org.reactivestreams:reactive-streams") optional("io.projectreactor:reactor-core") optional("io.projectreactor:reactor-test") + optional("org.jetbrains.kotlin:kotlin-stdlib:${kotlinVersion}") testCompile(project(":spring-context-support")) testCompile(project(":spring-oxm")) testCompile("javax.mail:javax.mail-api:${javamailVersion}") diff --git a/spring-test/src/main/java/org/springframework/test/web/reactive/server/WebTestClient.java b/spring-test/src/main/java/org/springframework/test/web/reactive/server/WebTestClient.java index c9e60c3836..7d02579f8a 100644 --- a/spring-test/src/main/java/org/springframework/test/web/reactive/server/WebTestClient.java +++ b/spring-test/src/main/java/org/springframework/test/web/reactive/server/WebTestClient.java @@ -536,7 +536,7 @@ public interface WebTestClient { */ BodySpec expectBody(ParameterizedTypeReference bodyType); - /** + /** * Declare expectations on the response body decoded to {@code List}. * @param elementType the expected List element type */ diff --git a/spring-test/src/main/kotlin/org/springframework/test/web/reactive/server/WebTestClientExtensions.kt b/spring-test/src/main/kotlin/org/springframework/test/web/reactive/server/WebTestClientExtensions.kt new file mode 100644 index 0000000000..5a3a461796 --- /dev/null +++ b/spring-test/src/main/kotlin/org/springframework/test/web/reactive/server/WebTestClientExtensions.kt @@ -0,0 +1,84 @@ +/* + * Copyright 2002-2017 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.test.web.reactive.server + +import org.reactivestreams.Publisher +import kotlin.reflect.KClass + +/** + * Extension for [WebTestClient.RequestBodySpec.body] providing a variant without explicit class + * parameter thanks to Kotlin reified type parameters. + * + * @author Sebastien Deleuze + * @since 5.0 + */ +inline fun > WebTestClient.RequestBodySpec.body(publisher: S): WebTestClient.RequestHeadersSpec<*> + = body(publisher, T::class.java) + +/** + * Extension for [WebTestClient.ResponseSpec.expectBody] providing a [KClass] based variant. + * + * @author Sebastien Deleuze + * @since 5.0 + */ +fun WebTestClient.ResponseSpec.expectBody(type: KClass): WebTestClient.BodySpec = + expectBody(type.java) + +/** + * Extension for [WebTestClient.ResponseSpec.expectBody] providing a `expectBody()` variant. + * + * @author Sebastien Deleuze + * @since 5.0 + */ +inline fun WebTestClient.ResponseSpec.expectBody(): WebTestClient.BodySpec = + expectBody(B::class.java) + +/** + * Extension for [WebTestClient.ResponseSpec.expectBodyList] providing a [KClass] based variant. + * + * @author Sebastien Deleuze + * @since 5.0 + */ +fun WebTestClient.ResponseSpec.expectBodyList(type: KClass): WebTestClient.ListBodySpec = + expectBodyList(type.java) + +/** + * Extension for [WebTestClient.ResponseSpec.expectBodyList] providing a `expectBodyList()` variant. + * + * @author Sebastien Deleuze + * @since 5.0 + */ +inline fun WebTestClient.ResponseSpec.expectBodyList(): WebTestClient.ListBodySpec = + expectBodyList(E::class.java) + +/** + * Extension for [WebTestClient.ResponseSpec.returnResult] providing a [KClass] based variant. + * + * @author Sebastien Deleuze + * @since 5.0 + */ +fun WebTestClient.ResponseSpec.returnResult(type: KClass): FluxExchangeResult = + returnResult(type.java) + +/** + * Extension for [WebTestClient.ResponseSpec.returnResult] providing a `returnResult()` variant. + * + * @author Sebastien Deleuze + * @since 5.0 + */ +inline fun WebTestClient.ResponseSpec.returnResult(): FluxExchangeResult = + returnResult(T::class.java) diff --git a/spring-test/src/test/kotlin/org/springframework/test/web/reactive/server/WebTestClientExtensionsTests.kt b/spring-test/src/test/kotlin/org/springframework/test/web/reactive/server/WebTestClientExtensionsTests.kt new file mode 100644 index 0000000000..5feb820236 --- /dev/null +++ b/spring-test/src/test/kotlin/org/springframework/test/web/reactive/server/WebTestClientExtensionsTests.kt @@ -0,0 +1,74 @@ +package org.springframework.test.web.reactive.server + +import com.nhaarman.mockito_kotlin.mock +import com.nhaarman.mockito_kotlin.times +import com.nhaarman.mockito_kotlin.verify +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.Answers +import org.mockito.Mock +import org.mockito.junit.MockitoJUnitRunner +import org.reactivestreams.Publisher + + +/** + * Mock object based tests for [WebTestClient] Kotlin extensions + * + * @author Sebastien Deleuze + */ +@RunWith(MockitoJUnitRunner::class) +class WebTestClientExtensionsTests { + + @Mock(answer = Answers.RETURNS_MOCKS) + lateinit var requestBodySpec: WebTestClient.RequestBodySpec + + @Mock(answer = Answers.RETURNS_MOCKS) + lateinit var responseSpec: WebTestClient.ResponseSpec + + + @Test + fun `RequestBodySpec#body with Publisher and reified type parameters`() { + val body = mock>() + requestBodySpec.body(body) + verify(requestBodySpec, times(1)).body(body, Foo::class.java) + } + + @Test + fun `ResponseSpec#expectBody with KClass`() { + responseSpec.expectBody(Foo::class) + verify(responseSpec, times(1)).expectBody(Foo::class.java) + } + + @Test + fun `ResponseSpec#expectBody with reified type parameters`() { + responseSpec.expectBody() + verify(responseSpec, times(1)).expectBody(Foo::class.java) + } + + @Test + fun `ResponseSpec#expectBodyList with KClass`() { + responseSpec.expectBodyList(Foo::class) + verify(responseSpec, times(1)).expectBodyList(Foo::class.java) + } + + @Test + fun `ResponseSpec#expectBodyList with reified type parameters`() { + responseSpec.expectBodyList() + verify(responseSpec, times(1)).expectBodyList(Foo::class.java) + } + + @Test + fun `ResponseSpec#returnResult with KClass`() { + responseSpec.returnResult(Foo::class) + verify(responseSpec, times(1)).returnResult(Foo::class.java) + } + + @Test + fun `ResponseSpec#returnResult with reified type parameters`() { + responseSpec.returnResult() + verify(responseSpec, times(1)).returnResult(Foo::class.java) + } + + class Foo + +}