diff --git a/spring-boot-project/spring-boot-test/src/main/kotlin/org/springframework/boot/test/web/client/TestRestTemplateExtensions.kt b/spring-boot-project/spring-boot-test/src/main/kotlin/org/springframework/boot/test/web/client/TestRestTemplateExtensions.kt index 747fae85728..7ab8fd4ec46 100644 --- a/spring-boot-project/spring-boot-test/src/main/kotlin/org/springframework/boot/test/web/client/TestRestTemplateExtensions.kt +++ b/spring-boot-project/spring-boot-test/src/main/kotlin/org/springframework/boot/test/web/client/TestRestTemplateExtensions.kt @@ -25,8 +25,10 @@ import org.springframework.web.client.RestClientException import java.net.URI /** - * Extension for [TestRestTemplate.getForObject] avoiding specifying the type - * parameter thanks to Kotlin reified type parameters. + * Extension for [TestRestTemplate.getForObject] providing a `getForObject(...)` + * variant leveraging Kotlin reified type parameters. Like the original Java method, this + * extension is subject to type erasure. Use [exchange] if you need to retain actual + * generic type arguments. * * @author Sebastien Deleuze * @since 2.0.0 @@ -36,8 +38,10 @@ inline fun TestRestTemplate.getForObject(url: String, vararg u getForObject(url, T::class.java, *uriVariables) /** - * Extension for [TestRestTemplate.getForObject] avoiding specifying the type - * parameter thanks to Kotlin reified type parameters. + * Extension for [TestRestTemplate.getForObject] providing a `getForObject(...)` + * variant leveraging Kotlin reified type parameters. Like the original Java method, this + * extension is subject to type erasure. Use [exchange] if you need to retain actual + * generic type arguments. * * @author Sebastien Deleuze * @since 2.0.0 @@ -47,8 +51,10 @@ inline fun TestRestTemplate.getForObject(url: String, uriVaria getForObject(url, T::class.java, uriVariables) /** - * Extension for [TestRestTemplate.getForObject] avoiding specifying the type parameter - * thanks to Kotlin reified type parameters. + * Extension for [TestRestTemplate.getForObject] providing a `getForObject(...)` + * variant leveraging Kotlin reified type parameters. Like the original Java method, this + * extension is subject to type erasure. Use [exchange] if you need to retain actual + * generic type arguments. * * @author Sebastien Deleuze * @since 2.0.0 @@ -58,8 +64,10 @@ inline fun TestRestTemplate.getForObject(url: URI): T? = getForObject(url, T::class.java) /** - * Extension for [TestRestTemplate.getForEntity] avoiding requiring the type parameter - * thanks to Kotlin reified type parameters. + * Extension for [TestRestTemplate.getForEntity] providing a `getForEntity(...)` + * variant leveraging Kotlin reified type parameters. Like the original Java method, this + * extension is subject to type erasure. Use [exchange] if you need to retain actual + * generic type arguments. * * @author Sebastien Deleuze * @since 2.0.0 @@ -69,8 +77,10 @@ inline fun TestRestTemplate.getForEntity(url: URI): ResponseEn getForEntity(url, T::class.java) /** - * Extension for [TestRestTemplate.getForEntity] avoiding requiring the type parameter - * thanks to Kotlin reified type parameters. + * Extension for [TestRestTemplate.getForEntity] providing a `getForEntity(...)` + * variant leveraging Kotlin reified type parameters. Like the original Java method, this + * extension is subject to type erasure. Use [exchange] if you need to retain actual + * generic type arguments. * * @author Sebastien Deleuze * @since 2.0.0 @@ -80,8 +90,10 @@ inline fun TestRestTemplate.getForEntity(url: String, vararg u getForEntity(url, T::class.java, *uriVariables) /** - * Extension for [TestRestTemplate.getForEntity] avoiding requiring the type parameter - * thanks to Kotlin reified type parameters. + * Extension for [TestRestTemplate.getForEntity] providing a `getForEntity(...)` + * variant leveraging Kotlin reified type parameters. Like the original Java method, this + * extension is subject to type erasure. Use [exchange] if you need to retain actual + * generic type arguments. * * @author Sebastien Deleuze * @since 2.0.0 @@ -91,140 +103,171 @@ inline fun TestRestTemplate.getForEntity(url: String, uriVaria getForEntity(url, T::class.java, uriVariables) /** - * Extension for [TestRestTemplate.patchForObject] avoiding specifying the type parameter - * thanks to Kotlin reified type parameters. + * Extension for [TestRestTemplate.patchForObject] providing a `patchForObject(...)` + * variant leveraging Kotlin reified type parameters. Like the original Java method, this + * extension is subject to type erasure. Use [exchange] if you need to retain actual + * generic type arguments. * * @author Sebastien Deleuze * @since 2.0.0 */ @Throws(RestClientException::class) -inline fun TestRestTemplate.patchForObject(url: String, request: Any, vararg uriVariables: Any): T? = +inline fun TestRestTemplate.patchForObject(url: String, request: Any? = null, + vararg uriVariables: Any): T? = patchForObject(url, request, T::class.java, *uriVariables) /** - * Extension for [TestRestTemplate.patchForObject] avoiding specifying the type parameter - * thanks to Kotlin reified type parameters. + * Extension for [TestRestTemplate.patchForObject] providing a `patchForObject(...)` + * variant leveraging Kotlin reified type parameters. Like the original Java method, this + * extension is subject to type erasure. Use [exchange] if you need to retain actual + * generic type arguments. * * @author Sebastien Deleuze * @since 2.0.0 */ @Throws(RestClientException::class) -inline fun TestRestTemplate.patchForObject(url: String, request: Any, uriVariables: Map): T? = +inline fun TestRestTemplate.patchForObject(url: String, request: Any? = null, + uriVariables: Map): T? = patchForObject(url, request, T::class.java, uriVariables) /** - * Extension for [TestRestTemplate.patchForObject] avoiding specifying the type parameter - * thanks to Kotlin reified type parameters. + * Extension for [TestRestTemplate.patchForObject] providing a `patchForObject(...)` + * variant leveraging Kotlin reified type parameters. Like the original Java method, this + * extension is subject to type erasure. Use [exchange] if you need to retain actual + * generic type arguments. * * @author Sebastien Deleuze * @since 2.0.0 */ @Throws(RestClientException::class) -inline fun TestRestTemplate.patchForObject(url: URI, request: Any): T? = +inline fun TestRestTemplate.patchForObject(url: URI, request: Any? = null): T? = patchForObject(url, request, T::class.java) /** - * Extension for [TestRestTemplate.postForObject] avoiding specifying the type parameter - * thanks to Kotlin reified type parameters. + * Extension for [TestRestTemplate.postForObject] providing a `postForObject(...)` + * variant leveraging Kotlin reified type parameters. Like the original Java method, this + * extension is subject to type erasure. Use [exchange] if you need to retain actual + * generic type arguments. * * @author Sebastien Deleuze * @since 2.0.0 */ @Throws(RestClientException::class) -inline fun TestRestTemplate.postForObject(url: String, request: Any, vararg uriVariables: Any): T? = +inline fun TestRestTemplate.postForObject(url: String, request: Any? = null, + vararg uriVariables: Any): T? = postForObject(url, request, T::class.java, *uriVariables) /** - * Extension for [TestRestTemplate.postForObject] avoiding specifying the type parameter - * thanks to Kotlin reified type parameters. + * Extension for [TestRestTemplate.postForObject] providing a `postForObject(...)` + * variant leveraging Kotlin reified type parameters. Like the original Java method, this + * extension is subject to type erasure. Use [exchange] if you need to retain actual + * generic type arguments. * * @author Sebastien Deleuze * @since 2.0.0 */ @Throws(RestClientException::class) -inline fun TestRestTemplate.postForObject(url: String, request: Any, uriVariables: Map): T? = +inline fun TestRestTemplate.postForObject(url: String, request: Any? = null, + uriVariables: Map): T? = postForObject(url, request, T::class.java, uriVariables) /** - * Extension for [TestRestTemplate.postForObject] avoiding specifying the type parameter - * thanks to Kotlin reified type parameters. + * Extension for [TestRestTemplate.postForObject] providing a `postForObject(...)` + * variant leveraging Kotlin reified type parameters. Like the original Java method, this + * extension is subject to type erasure. Use [exchange] if you need to retain actual + * generic type arguments. * * @author Sebastien Deleuze * @since 2.0.0 */ @Throws(RestClientException::class) -inline fun TestRestTemplate.postForObject(url: URI, request: Any): T? = +inline fun TestRestTemplate.postForObject(url: URI, request: Any? = null): T? = postForObject(url, request, T::class.java) /** - * Extension for [TestRestTemplate.postForEntity] avoiding specifying the type parameter - * thanks to Kotlin reified type parameters. + * Extension for [TestRestTemplate.postForEntity] providing a `postForEntity(...)` + * variant leveraging Kotlin reified type parameters. Like the original Java method, this + * extension is subject to type erasure. Use [exchange] if you need to retain actual + * generic type arguments. * * @author Sebastien Deleuze * @since 2.0.0 */ @Throws(RestClientException::class) -inline fun TestRestTemplate.postForEntity(url: String, request: Any, vararg uriVariables: Any): ResponseEntity = +inline fun TestRestTemplate.postForEntity(url: String, request: Any? = null, + vararg uriVariables: Any): ResponseEntity = postForEntity(url, request, T::class.java, *uriVariables) /** - * Extension for [TestRestTemplate.postForEntity] avoiding specifying the type parameter - * thanks to Kotlin reified type parameters. + * Extension for [TestRestTemplate.postForEntity] providing a `postForEntity(...)` + * variant leveraging Kotlin reified type parameters. Like the original Java method, this + * extension is subject to type erasure. Use [exchange] if you need to retain actual + * generic type arguments. * * @author Sebastien Deleuze * @since 2.0.0 */ @Throws(RestClientException::class) -inline fun TestRestTemplate.postForEntity(url: String, request: Any, uriVariables: Map): ResponseEntity = +inline fun TestRestTemplate.postForEntity(url: String, request: Any? = null, + uriVariables: Map): ResponseEntity = postForEntity(url, request, T::class.java, uriVariables) /** - * Extension for [TestRestTemplate.postForEntity] avoiding specifying the type parameter - * thanks to Kotlin reified type parameters. + * Extension for [TestRestTemplate.postForEntity] providing a `postForEntity(...)` + * variant leveraging Kotlin reified type parameters. Like the original Java method, this + * extension is subject to type erasure. Use [exchange] if you need to retain actual + * generic type arguments. * * @author Sebastien Deleuze * @since 2.0.0 */ @Throws(RestClientException::class) -inline fun TestRestTemplate.postForEntity(url: URI, request: Any): ResponseEntity = +inline fun TestRestTemplate.postForEntity(url: URI, request: Any? = null): ResponseEntity = postForEntity(url, request, T::class.java) /** - * Extension for [TestRestTemplate.exchange] avoiding specifying the type parameter - * thanks to Kotlin reified type parameters. + * Extension for [TestRestTemplate.exchange] providing an `exchange(...)` + * variant leveraging Kotlin reified type parameters. This extension is not subject to + * type erasure and retains actual generic type arguments. * * @author Sebastien Deleuze * @since 2.0.0 */ @Throws(RestClientException::class) -inline fun TestRestTemplate.exchange(url: String, method: HttpMethod, requestEntity: HttpEntity<*>, vararg uriVariables: Any): ResponseEntity = +inline fun TestRestTemplate.exchange(url: String, method: HttpMethod, + requestEntity: HttpEntity<*>? = null, vararg uriVariables: Any): ResponseEntity = exchange(url, method, requestEntity, object : ParameterizedTypeReference() {}, *uriVariables) /** - * Extension for [TestRestTemplate.exchange] avoiding specifying the type parameter - * thanks to Kotlin reified type parameters. + * Extension for [TestRestTemplate.exchange] providing an `exchange(...)` + * variant leveraging Kotlin reified type parameters. This extension is not subject to + * type erasure and retains actual generic type arguments. * * @author Sebastien Deleuze * @since 2.0.0 */ @Throws(RestClientException::class) -inline fun TestRestTemplate.exchange(url: String, method: HttpMethod, requestEntity: HttpEntity<*>, uriVariables: Map): ResponseEntity = +inline fun TestRestTemplate.exchange(url: String, method: HttpMethod, + requestEntity: HttpEntity<*>? = null, uriVariables: Map): ResponseEntity = exchange(url, method, requestEntity, object : ParameterizedTypeReference() {}, uriVariables) /** - * Extension for [TestRestTemplate.exchange] avoiding specifying the type parameter - * thanks to Kotlin reified type parameters. + * Extension for [TestRestTemplate.exchange] providing an `exchange(...)` + * variant leveraging Kotlin reified type parameters. This extension is not subject to + * type erasure and retains actual generic type arguments. * * @author Sebastien Deleuze * @since 2.0.0 */ @Throws(RestClientException::class) -inline fun TestRestTemplate.exchange(url: URI, method: HttpMethod, requestEntity: HttpEntity<*>): ResponseEntity = +inline fun TestRestTemplate.exchange(url: URI, method: HttpMethod, + requestEntity: HttpEntity<*>? = null): ResponseEntity = exchange(url, method, requestEntity, object : ParameterizedTypeReference() {}) /** - * Extension for [TestRestTemplate.exchange] avoiding specifying the type parameter - * thanks to Kotlin reified type parameters. + * Extension for [TestRestTemplate.exchange] providing an `exchange(...)` + * variant leveraging Kotlin reified type parameters. This extension is not subject to + * type erasure and retains actual generic type arguments. * * @author Sebastien Deleuze * @since 2.0.0 diff --git a/spring-boot-project/spring-boot-test/src/test/kotlin/org/springframework/boot/test/web/client/TestRestTemplateExtensionsTests.kt b/spring-boot-project/spring-boot-test/src/test/kotlin/org/springframework/boot/test/web/client/TestRestTemplateExtensionsTests.kt index 8239f05d10f..bf3a45e3ceb 100644 --- a/spring-boot-project/spring-boot-test/src/test/kotlin/org/springframework/boot/test/web/client/TestRestTemplateExtensionsTests.kt +++ b/spring-boot-project/spring-boot-test/src/test/kotlin/org/springframework/boot/test/web/client/TestRestTemplateExtensionsTests.kt @@ -122,6 +122,13 @@ class TestRestTemplateExtensionsTests { verify(template, times(1)).patchForObject(url, body, Foo::class.java) } + @Test + fun `patchForObject with reified type parameters`() { + val url = "https://spring.io" + template.patchForObject(url) + verify(template, times(1)).patchForObject(url, null, Foo::class.java) + } + @Test fun `postForObject with reified type parameters, String, Any and varargs`() { val url = "https://spring.io" @@ -149,6 +156,13 @@ class TestRestTemplateExtensionsTests { verify(template, times(1)).postForObject(url, body, Foo::class.java) } + @Test + fun `postForObject with reified type parameters`() { + val url = "https://spring.io" + template.postForObject(url) + verify(template, times(1)).postForObject(url, null, Foo::class.java) + } + @Test fun `postForEntity with reified type parameters, String, Any and varargs`() { val url = "https://spring.io" @@ -176,6 +190,13 @@ class TestRestTemplateExtensionsTests { verify(template, times(1)).postForEntity(url, body, Foo::class.java) } + @Test + fun `postForEntity with reified type parameters`() { + val url = "https://spring.io" + template.postForEntity(url) + verify(template, times(1)).postForEntity(url, null, Foo::class.java) + } + @Test fun `exchange with reified type parameters, String, HttpMethod, HttpEntity and varargs`() { val url = "https://spring.io" @@ -217,6 +238,15 @@ class TestRestTemplateExtensionsTests { object : ParameterizedTypeReference>() {}) } + @Test + fun `exchange with reified type parameters, String and HttpMethod`() { + val url = "https://spring.io" + val method = HttpMethod.GET + template.exchange>(url, method) + verify(template, times(1)).exchange(url, method, null, + object : ParameterizedTypeReference>() {}) + } + @Test fun `RestOperations are available`() { val extensions = Class.forName(