Commit 6e0a2510 authored by Stephane Nicoll's avatar Stephane Nicoll

Merge pull request #11039 from sdeleuze:test-rest-template-extensions

* pr/11039:
  Polish "Introduce TestRestTemplate Kotlin extensions"
  Introduce TestRestTemplate Kotlin extensions
parents 7f8ca64d aa87c45b
...@@ -53,6 +53,25 @@ ...@@ -53,6 +53,25 @@
<artifactId>log4j</artifactId> <artifactId>log4j</artifactId>
<version>1.2.17</version> <version>1.2.17</version>
</dependency> </dependency>
<dependency>
<groupId>com.nhaarman</groupId>
<artifactId>mockito-kotlin</artifactId>
<version>1.5.0</version>
<exclusions>
<exclusion>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-stdlib</artifactId>
</exclusion>
<exclusion>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-reflect</artifactId>
</exclusion>
<exclusion>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency> <dependency>
<groupId>com.squareup.okhttp</groupId> <groupId>com.squareup.okhttp</groupId>
<artifactId>okhttp</artifactId> <artifactId>okhttp</artifactId>
......
...@@ -75,6 +75,16 @@ ...@@ -75,6 +75,16 @@
<artifactId>hamcrest-library</artifactId> <artifactId>hamcrest-library</artifactId>
<optional>true</optional> <optional>true</optional>
</dependency> </dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-stdlib</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-reflect</artifactId>
<optional>true</optional>
</dependency>
<dependency> <dependency>
<groupId>org.mockito</groupId> <groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId> <artifactId>mockito-core</artifactId>
...@@ -182,6 +192,11 @@ ...@@ -182,6 +192,11 @@
<artifactId>junit-jupiter-api</artifactId> <artifactId>junit-jupiter-api</artifactId>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency>
<groupId>com.nhaarman</groupId>
<artifactId>mockito-kotlin</artifactId>
<scope>test</scope>
</dependency>
</dependencies> </dependencies>
<build> <build>
<plugins> <plugins>
...@@ -196,6 +211,66 @@ ...@@ -196,6 +211,66 @@
</execution> </execution>
</executions> </executions>
</plugin> </plugin>
<plugin>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-maven-plugin</artifactId>
<executions>
<execution>
<id>compile</id>
<phase>compile</phase>
<goals>
<goal>compile</goal>
</goals>
<configuration>
<sourceDirs>
<sourceDir>${project.basedir}/src/main/kotlin</sourceDir>
<sourceDir>${project.basedir}/src/main/java</sourceDir>
</sourceDirs>
</configuration>
</execution>
<execution>
<id>test-compile</id>
<phase>test-compile</phase>
<goals>
<goal>test-compile</goal>
</goals>
<configuration>
<sourceDirs>
<sourceDir>${project.basedir}/src/test/kotlin</sourceDir>
<sourceDir>${project.basedir}/src/test/java</sourceDir>
</sourceDirs>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<executions>
<execution>
<id>default-compile</id>
<phase>none</phase>
</execution>
<execution>
<id>default-testCompile</id>
<phase>none</phase>
</execution>
<execution>
<id>java-compile</id>
<phase>compile</phase>
<goals>
<goal>compile</goal>
</goals>
</execution>
<execution>
<id>java-test-compile</id>
<phase>test-compile</phase>
<goals>
<goal>testCompile</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins> </plugins>
</build> </build>
</project> </project>
/*
* Copyright 2012-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.boot.test.web.client
import org.springframework.core.ParameterizedTypeReference
import org.springframework.http.HttpEntity
import org.springframework.http.HttpMethod
import org.springframework.http.RequestEntity
import org.springframework.http.ResponseEntity
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.
*
* @author Sebastien Deleuze
* @since 2.0.0
*/
@Throws(RestClientException::class)
inline fun <reified T : Any> TestRestTemplate.getForObject(url: String, vararg uriVariables: Any): T? =
getForObject(url, T::class.java, *uriVariables)
/**
* Extension for [TestRestTemplate.getForObject] avoiding specifying the type
* parameter thanks to Kotlin reified type parameters.
*
* @author Sebastien Deleuze
* @since 2.0.0
*/
@Throws(RestClientException::class)
inline fun <reified T : Any> TestRestTemplate.getForObject(url: String, uriVariables: Map<String, Any?>): T? =
getForObject(url, T::class.java, uriVariables)
/**
* Extension for [TestRestTemplate.getForObject] avoiding specifying the type parameter
* thanks to Kotlin reified type parameters.
*
* @author Sebastien Deleuze
* @since 2.0.0
*/
@Throws(RestClientException::class)
inline fun <reified T : Any> 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.
*
* @author Sebastien Deleuze
* @since 2.0.0
*/
@Throws(RestClientException::class)
inline fun <reified T : Any> TestRestTemplate.getForEntity(url: URI): ResponseEntity<T> =
getForEntity(url, T::class.java)
/**
* Extension for [TestRestTemplate.getForEntity] avoiding requiring the type parameter
* thanks to Kotlin reified type parameters.
*
* @author Sebastien Deleuze
* @since 2.0.0
*/
@Throws(RestClientException::class)
inline fun <reified T : Any> TestRestTemplate.getForEntity(url: String, vararg uriVariables: Any): ResponseEntity<T> =
getForEntity(url, T::class.java, *uriVariables)
/**
* Extension for [TestRestTemplate.getForEntity] avoiding requiring the type parameter
* thanks to Kotlin reified type parameters.
*
* @author Sebastien Deleuze
* @since 2.0.0
*/
@Throws(RestClientException::class)
inline fun <reified T : Any> TestRestTemplate.getForEntity(url: String, uriVariables: Map<String, *>): ResponseEntity<T> =
getForEntity(url, T::class.java, uriVariables)
/**
* Extension for [TestRestTemplate.patchForObject] avoiding specifying the type parameter
* thanks to Kotlin reified type parameters.
*
* @author Sebastien Deleuze
* @since 2.0.0
*/
@Throws(RestClientException::class)
inline fun <reified T : Any> TestRestTemplate.patchForObject(url: String, request: Any, 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.
*
* @author Sebastien Deleuze
* @since 2.0.0
*/
@Throws(RestClientException::class)
inline fun <reified T : Any> TestRestTemplate.patchForObject(url: String, request: Any, uriVariables: Map<String, *>): T? =
patchForObject(url, request, T::class.java, uriVariables)
/**
* Extension for [TestRestTemplate.patchForObject] avoiding specifying the type parameter
* thanks to Kotlin reified type parameters.
*
* @author Sebastien Deleuze
* @since 2.0.0
*/
@Throws(RestClientException::class)
inline fun <reified T : Any> TestRestTemplate.patchForObject(url: URI, request: Any): T? =
patchForObject(url, request, T::class.java)
/**
* Extension for [TestRestTemplate.postForObject] avoiding specifying the type parameter
* thanks to Kotlin reified type parameters.
*
* @author Sebastien Deleuze
* @since 2.0.0
*/
@Throws(RestClientException::class)
inline fun <reified T : Any> TestRestTemplate.postForObject(url: String, request: Any, 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.
*
* @author Sebastien Deleuze
* @since 2.0.0
*/
@Throws(RestClientException::class)
inline fun <reified T : Any> TestRestTemplate.postForObject(url: String, request: Any, uriVariables: Map<String, *>): T? =
postForObject(url, request, T::class.java, uriVariables)
/**
* Extension for [TestRestTemplate.postForObject] avoiding specifying the type parameter
* thanks to Kotlin reified type parameters.
*
* @author Sebastien Deleuze
* @since 2.0.0
*/
@Throws(RestClientException::class)
inline fun <reified T : Any> TestRestTemplate.postForObject(url: URI, request: Any): T? =
postForObject(url, request, T::class.java)
/**
* Extension for [TestRestTemplate.postForEntity] avoiding specifying the type parameter
* thanks to Kotlin reified type parameters.
*
* @author Sebastien Deleuze
* @since 2.0.0
*/
@Throws(RestClientException::class)
inline fun <reified T : Any> TestRestTemplate.postForEntity(url: String, request: Any, vararg uriVariables: Any): ResponseEntity<T> =
postForEntity(url, request, T::class.java, *uriVariables)
/**
* Extension for [TestRestTemplate.postForEntity] avoiding specifying the type parameter
* thanks to Kotlin reified type parameters.
*
* @author Sebastien Deleuze
* @since 2.0.0
*/
@Throws(RestClientException::class)
inline fun <reified T : Any> TestRestTemplate.postForEntity(url: String, request: Any, uriVariables: Map<String, *>): ResponseEntity<T> =
postForEntity(url, request, T::class.java, uriVariables)
/**
* Extension for [TestRestTemplate.postForEntity] avoiding specifying the type parameter
* thanks to Kotlin reified type parameters.
*
* @author Sebastien Deleuze
* @since 2.0.0
*/
@Throws(RestClientException::class)
inline fun <reified T : Any> TestRestTemplate.postForEntity(url: URI, request: Any): ResponseEntity<T> =
postForEntity(url, request, T::class.java)
/**
* Extension for [TestRestTemplate.exchange] avoiding specifying the type parameter
* thanks to Kotlin reified type parameters.
*
* @author Sebastien Deleuze
* @since 2.0.0
*/
@Throws(RestClientException::class)
inline fun <reified T : Any> TestRestTemplate.exchange(url: String, method: HttpMethod, requestEntity: HttpEntity<*>, vararg uriVariables: Any): ResponseEntity<T> =
exchange(url, method, requestEntity, object : ParameterizedTypeReference<T>() {}, *uriVariables)
/**
* Extension for [TestRestTemplate.exchange] avoiding specifying the type parameter
* thanks to Kotlin reified type parameters.
*
* @author Sebastien Deleuze
* @since 2.0.0
*/
@Throws(RestClientException::class)
inline fun <reified T : Any> TestRestTemplate.exchange(url: String, method: HttpMethod, requestEntity: HttpEntity<*>, uriVariables: Map<String, *>): ResponseEntity<T> =
exchange(url, method, requestEntity, object : ParameterizedTypeReference<T>() {}, uriVariables)
/**
* Extension for [TestRestTemplate.exchange] avoiding specifying the type parameter
* thanks to Kotlin reified type parameters.
*
* @author Sebastien Deleuze
* @since 2.0.0
*/
@Throws(RestClientException::class)
inline fun <reified T : Any> TestRestTemplate.exchange(url: URI, method: HttpMethod, requestEntity: HttpEntity<*>): ResponseEntity<T> =
exchange(url, method, requestEntity, object : ParameterizedTypeReference<T>() {})
/**
* Extension for [TestRestTemplate.exchange] avoiding specifying the type parameter
* thanks to Kotlin reified type parameters.
*
* @author Sebastien Deleuze
* @since 2.0.0
*/
@Throws(RestClientException::class)
inline fun <reified T : Any> TestRestTemplate.exchange(requestEntity: RequestEntity<*>): ResponseEntity<T> =
exchange(requestEntity, object : ParameterizedTypeReference<T>() {})
\ No newline at end of file
/*
* Copyright 2012-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.boot.test.web.client
import com.nhaarman.mockito_kotlin.mock
import org.junit.Assert
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Answers
import org.mockito.Mock
import org.mockito.Mockito.times
import org.mockito.Mockito.verify
import org.mockito.junit.MockitoJUnitRunner
import org.springframework.core.ParameterizedTypeReference
import org.springframework.http.HttpEntity
import org.springframework.http.HttpMethod
import org.springframework.http.RequestEntity
import org.springframework.util.ReflectionUtils
import org.springframework.web.client.RestOperations
import java.net.URI
import kotlin.reflect.full.createType
import kotlin.reflect.jvm.kotlinFunction
/**
* Mock object based tests for [TestRestTemplate] Kotlin extensions
*
* @author Sebastien Deleuze
*/
@RunWith(MockitoJUnitRunner::class)
class TestRestTemplateExtensionsTests {
@Mock(answer = Answers.RETURNS_MOCKS)
lateinit var template: TestRestTemplate
@Test
fun `getForObject with reified type parameters, String and varargs`() {
val url = "https://spring.io"
val var1 = "var1"
val var2 = "var2"
template.getForObject<Foo>(url, var1, var2)
template.restTemplate
verify(template, times(1)).getForObject(url, Foo::class.java, var1, var2)
}
@Test
fun `getForObject with reified type parameters, String and Map`() {
val url = "https://spring.io"
val vars = mapOf(Pair("key1", "value1"), Pair("key2", "value2"))
template.getForObject<Foo>(url, vars)
verify(template, times(1)).getForObject(url, Foo::class.java, vars)
}
@Test
fun `getForObject with reified type parameters and URI`() {
val url = URI("https://spring.io")
template.getForObject<Foo>(url)
verify(template, times(1)).getForObject(url, Foo::class.java)
}
@Test
fun `getForEntity with reified type parameters, String and URI`() {
val url = URI("https://spring.io")
template.getForEntity<Foo>(url)
verify(template, times(1)).getForEntity(url, Foo::class.java)
}
@Test
fun `getForEntity with reified type parameters, String and varargs`() {
val url = "https://spring.io"
val var1 = "var1"
val var2 = "var2"
template.getForEntity<Foo>(url, var1, var2)
verify(template, times(1)).getForEntity(url, Foo::class.java, var1, var2)
}
@Test
fun `getForEntity with reified type parameters and Map`() {
val url = "https://spring.io"
val vars = mapOf(Pair("key1", "value1"), Pair("key2", "value2"))
template.getForEntity<Foo>(url, vars)
verify(template, times(1)).getForEntity(url, Foo::class.java, vars)
}
@Test
fun `patchForObject with reified type parameters, String and varargs`() {
val url = "https://spring.io"
val body: Any = "body"
val var1 = "var1"
val var2 = "var2"
template.patchForObject<Foo>(url, body, var1, var2)
verify(template, times(1)).patchForObject(url, body, Foo::class.java, var1, var2)
}
@Test
fun `patchForObject with reified type parameters, String and Map`() {
val url = "https://spring.io"
val body: Any = "body"
val vars = mapOf(Pair("key1", "value1"), Pair("key2", "value2"))
template.patchForObject<Foo>(url, body, vars)
verify(template, times(1)).patchForObject(url, body, Foo::class.java, vars)
}
@Test
fun `patchForObject with reified type parameters`() {
val url = "https://spring.io"
val body: Any = "body"
template.patchForObject<Foo>(url, body)
verify(template, times(1)).patchForObject(url, body, Foo::class.java)
}
@Test
fun `postForObject with reified type parameters, String and varargs`() {
val url = "https://spring.io"
val body: Any = "body"
val var1 = "var1"
val var2 = "var2"
template.postForObject<Foo>(url, body, var1, var2)
verify(template, times(1)).postForObject(url, body, Foo::class.java, var1, var2)
}
@Test
fun `postForObject with reified type parameters, String and Map`() {
val url = "https://spring.io"
val body: Any = "body"
val vars = mapOf(Pair("key1", "value1"), Pair("key2", "value2"))
template.postForObject<Foo>(url, body, vars)
verify(template, times(1)).postForObject(url, body, Foo::class.java, vars)
}
@Test
fun `postForObject with reified type parameters`() {
val url = "https://spring.io"
val body: Any = "body"
template.postForObject<Foo>(url, body)
verify(template, times(1)).postForObject(url, body, Foo::class.java)
}
@Test
fun `postForEntity with reified type parameters, String and varargs`() {
val url = "https://spring.io"
val body: Any = "body"
val var1 = "var1"
val var2 = "var2"
template.postForEntity<Foo>(url, body, var1, var2)
verify(template, times(1)).postForEntity(url, body, Foo::class.java, var1, var2)
}
@Test
fun `postForEntity with reified type parameters, String and Map`() {
val url = "https://spring.io"
val body: Any = "body"
val vars = mapOf(Pair("key1", "value1"), Pair("key2", "value2"))
template.postForEntity<Foo>(url, body, vars)
verify(template, times(1)).postForEntity(url, body, Foo::class.java, vars)
}
@Test
fun `postForEntity with reified type parameters`() {
val url = "https://spring.io"
val body: Any = "body"
template.postForEntity<Foo>(url, body)
verify(template, times(1)).postForEntity(url, body, Foo::class.java)
}
@Test
fun `exchange with reified type parameters, String, HttpMethod, HttpEntity and varargs`() {
val url = "https://spring.io"
val method = HttpMethod.GET
val entity = mock<HttpEntity<Foo>>()
val var1 = "var1"
val var2 = "var2"
template.exchange<List<Foo>>(url, method, entity, var1, var2)
verify(template, times(1)).exchange(url, method, entity,
object : ParameterizedTypeReference<List<Foo>>() {}, var1, var2)
}
@Test
fun `exchange with reified type parameters, String, HttpMethod, HttpEntity and Map`() {
val url = "https://spring.io"
val method = HttpMethod.GET
val entity = mock<HttpEntity<Foo>>()
val vars = mapOf(Pair("key1", "value1"), Pair("key2", "value2"))
template.exchange<List<Foo>>(url, method, entity, vars)
verify(template, times(1)).exchange(url, method, entity,
object : ParameterizedTypeReference<List<Foo>>() {}, vars)
}
@Test
fun `exchange with reified type parameters, String, HttpMethod, HttpEntity`() {
val url = "https://spring.io"
val method = HttpMethod.GET
val entity = mock<HttpEntity<Foo>>()
template.exchange<List<Foo>>(url, method, entity)
verify(template, times(1)).exchange(url, method, entity,
object : ParameterizedTypeReference<List<Foo>>() {})
}
@Test
fun `exchange with reified type parameters, String, HttpEntity`() {
val entity = mock<RequestEntity<Foo>>()
template.exchange<List<Foo>>(entity)
verify(template, times(1)).exchange(entity,
object : ParameterizedTypeReference<List<Foo>>() {})
}
@Test
fun `RestOperations are available`() {
val extensions = Class.forName(
"org.springframework.boot.test.web.client.TestRestTemplateExtensionsKt")
ReflectionUtils.doWithMethods(RestOperations::class.java) { method ->
arrayOf(ParameterizedTypeReference::class, Class::class).forEach { kClass ->
if (method.parameterTypes.contains(kClass.java)) {
val parameters = mutableListOf<Class<*>>(TestRestTemplate::class.java)
.apply { addAll(method.parameterTypes.filter { it != kClass.java }) }
val f = extensions.getDeclaredMethod(method.name,
*parameters.toTypedArray()).kotlinFunction!!
Assert.assertEquals(1, f.typeParameters.size)
Assert.assertEquals(listOf(Any::class.createType()),
f.typeParameters[0].upperBounds)
}
}
}
}
class Foo
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment