Browse Source

Leverage JUnit 6 suspending function support

Closes gh-36215
pull/36221/head
Sébastien Deleuze 1 week ago
parent
commit
bc01eeb433
  1. 31
      integration-tests/src/test/kotlin/org/springframework/aop/framework/autoproxy/AspectJAutoProxyInterceptorKotlinIntegrationTests.kt
  2. 19
      spring-aop/src/test/kotlin/org/springframework/aop/framework/CoroutinesUtilsTests.kt
  3. 81
      spring-context/src/test/kotlin/org/springframework/cache/KotlinCacheReproTests.kt
  4. 2
      spring-context/src/test/kotlin/org/springframework/validation/beanvalidation/MethodValidationKotlinTests.kt
  5. 108
      spring-core/src/test/kotlin/org/springframework/core/CoroutinesUtilsTests.kt
  6. 9
      spring-core/src/test/kotlin/org/springframework/core/ReactiveAdapterRegistryKotlinTests.kt
  7. 51
      spring-messaging/src/test/kotlin/org/springframework/messaging/rsocket/RSocketRequesterExtensionsTests.kt
  8. 11
      spring-messaging/src/test/kotlin/org/springframework/messaging/rsocket/service/RSocketServiceMethodKotlinTests.kt
  9. 33
      spring-r2dbc/src/test/kotlin/org/springframework/r2dbc/core/DatabaseClientExtensionsTests.kt
  10. 60
      spring-r2dbc/src/test/kotlin/org/springframework/r2dbc/core/RowsFetchSpecExtensionsTests.kt
  11. 9
      spring-r2dbc/src/test/kotlin/org/springframework/r2dbc/core/UpdatedRowsFetchSpecExtensionsTests.kt
  12. 32
      spring-tx/src/test/kotlin/org/springframework/transaction/annotation/CoroutinesAnnotationTransactionInterceptorTests.kt
  13. 57
      spring-tx/src/test/kotlin/org/springframework/transaction/interceptor/AbstractCoroutinesTransactionAspectTests.kt
  14. 49
      spring-tx/src/test/kotlin/org/springframework/transaction/reactive/TransactionalOperatorExtensionsTests.kt
  15. 29
      spring-web/src/test/kotlin/org/springframework/web/server/ServerWebExchangeExtensionsTest.kt
  16. 3
      spring-web/src/test/kotlin/org/springframework/web/service/invoker/HttpServiceMethodKotlinTests.kt
  17. 61
      spring-webflux/src/test/kotlin/org/springframework/web/reactive/function/client/ClientResponseExtensionsTests.kt
  18. 7
      spring-webflux/src/test/kotlin/org/springframework/web/reactive/function/client/CoExchangeFilterFunctionTests.kt
  19. 64
      spring-webflux/src/test/kotlin/org/springframework/web/reactive/function/client/WebClientExtensionsTests.kt
  20. 19
      spring-webflux/src/test/kotlin/org/springframework/web/reactive/function/client/support/WebClientHttpServiceProxyKotlinTests.kt
  21. 7
      spring-webflux/src/test/kotlin/org/springframework/web/reactive/function/server/RenderingResponseExtensionsTests.kt
  22. 49
      spring-webflux/src/test/kotlin/org/springframework/web/reactive/function/server/ServerRequestExtensionsTests.kt
  23. 37
      spring-webflux/src/test/kotlin/org/springframework/web/reactive/function/server/ServerResponseExtensionsTests.kt

31
integration-tests/src/test/kotlin/org/springframework/aop/framework/autoproxy/AspectJAutoProxyInterceptorKotlinIntegrationTests.kt

@ -17,7 +17,6 @@
package org.springframework.aop.framework.autoproxy package org.springframework.aop.framework.autoproxy
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
import kotlinx.coroutines.runBlocking
import org.aopalliance.intercept.MethodInterceptor import org.aopalliance.intercept.MethodInterceptor
import org.aopalliance.intercept.MethodInvocation import org.aopalliance.intercept.MethodInvocation
import org.aspectj.lang.ProceedingJoinPoint import org.aspectj.lang.ProceedingJoinPoint
@ -73,43 +72,37 @@ class AspectJAutoProxyInterceptorKotlinIntegrationTests(
} }
@Test @Test
fun `Multiple interceptors with suspending function`() { suspend fun `Multiple interceptors with suspending function`() {
assertThat(firstAdvisor.interceptor.invocations).isEmpty() assertThat(firstAdvisor.interceptor.invocations).isEmpty()
assertThat(secondAdvisor.interceptor.invocations).isEmpty() assertThat(secondAdvisor.interceptor.invocations).isEmpty()
val value = "Hello!" val value = "Hello!"
runBlocking { assertThat(echo.suspendingEcho(value)).isEqualTo(value)
assertThat(echo.suspendingEcho(value)).isEqualTo(value)
}
assertThat(firstAdvisor.interceptor.invocations).singleElement().matches { Mono::class.java.isAssignableFrom(it) } assertThat(firstAdvisor.interceptor.invocations).singleElement().matches { Mono::class.java.isAssignableFrom(it) }
assertThat(secondAdvisor.interceptor.invocations).singleElement().matches { Mono::class.java.isAssignableFrom(it) } assertThat(secondAdvisor.interceptor.invocations).singleElement().matches { Mono::class.java.isAssignableFrom(it) }
} }
@Test // gh-33095 @Test // gh-33095
fun `Aspect and reactive transactional with suspending function`() { suspend fun `Aspect and reactive transactional with suspending function`() {
assertThat(countingAspect.counter).isZero() assertThat(countingAspect.counter).isZero()
assertThat(reactiveTransactionManager.commits).isZero() assertThat(reactiveTransactionManager.commits).isZero()
val value = "Hello!" val value = "Hello!"
runBlocking { assertThat(echo.suspendingTransactionalEcho(value)).isEqualTo(value)
assertThat(echo.suspendingTransactionalEcho(value)).isEqualTo(value)
}
assertThat(countingAspect.counter).`as`("aspect applied").isOne() assertThat(countingAspect.counter).`as`("aspect applied").isOne()
assertThat(reactiveTransactionManager.begun).isOne() assertThat(reactiveTransactionManager.begun).isOne()
assertThat(reactiveTransactionManager.commits).`as`("transactional applied").isOne() assertThat(reactiveTransactionManager.commits).`as`("transactional applied").isOne()
} }
@Test // gh-33210 @Test // gh-33210
fun `Aspect and cacheable with suspending function`() { suspend fun `Aspect and cacheable with suspending function`() {
assertThat(countingAspect.counter).isZero() assertThat(countingAspect.counter).isZero()
val value = "Hello!" val value = "Hello!"
runBlocking { assertThat(echo.suspendingCacheableEcho(value)).isEqualTo("$value 0")
assertThat(echo.suspendingCacheableEcho(value)).isEqualTo("$value 0") assertThat(echo.suspendingCacheableEcho(value)).isEqualTo("$value 0")
assertThat(echo.suspendingCacheableEcho(value)).isEqualTo("$value 0") assertThat(echo.suspendingCacheableEcho(value)).isEqualTo("$value 0")
assertThat(echo.suspendingCacheableEcho(value)).isEqualTo("$value 0") assertThat(countingAspect.counter).`as`("aspect applied once").isOne()
assertThat(countingAspect.counter).`as`("aspect applied once").isOne()
assertThat(echo.suspendingCacheableEcho("$value bis")).isEqualTo("$value bis 1")
assertThat(echo.suspendingCacheableEcho("$value bis")).isEqualTo("$value bis 1") assertThat(echo.suspendingCacheableEcho("$value bis")).isEqualTo("$value bis 1")
assertThat(echo.suspendingCacheableEcho("$value bis")).isEqualTo("$value bis 1")
}
assertThat(countingAspect.counter).`as`("aspect applied once per key").isEqualTo(2) assertThat(countingAspect.counter).`as`("aspect applied once per key").isEqualTo(2)
} }

19
spring-aop/src/test/kotlin/org/springframework/aop/framework/CoroutinesUtilsTests.kt

@ -19,7 +19,6 @@ package org.springframework.aop.framework
import kotlinx.coroutines.CoroutineName import kotlinx.coroutines.CoroutineName
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.toList import kotlinx.coroutines.flow.toList
import kotlinx.coroutines.runBlocking
import org.assertj.core.api.Assertions.assertThat import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.Test import org.junit.jupiter.api.Test
import reactor.core.publisher.Flux import reactor.core.publisher.Flux
@ -37,39 +36,31 @@ class CoroutinesUtilsTests {
fun awaitSingleNonNullValue() { fun awaitSingleNonNullValue() {
val value = "foo" val value = "foo"
val continuation = Continuation<Any>(CoroutineName("test")) { } val continuation = Continuation<Any>(CoroutineName("test")) { }
runBlocking { assertThat(CoroutinesUtils.awaitSingleOrNull(value, continuation)).isEqualTo(value)
assertThat(CoroutinesUtils.awaitSingleOrNull(value, continuation)).isEqualTo(value)
}
} }
@Test @Test
fun awaitSingleNullValue() { fun awaitSingleNullValue() {
val value = null val value = null
val continuation = Continuation<Any>(CoroutineName("test")) { } val continuation = Continuation<Any>(CoroutineName("test")) { }
runBlocking { assertThat(CoroutinesUtils.awaitSingleOrNull(value, continuation)).isNull()
assertThat(CoroutinesUtils.awaitSingleOrNull(value, continuation)).isNull()
}
} }
@Test @Test
fun awaitSingleMonoValue() { fun awaitSingleMonoValue() {
val value = "foo" val value = "foo"
val continuation = Continuation<Any>(CoroutineName("test")) { } val continuation = Continuation<Any>(CoroutineName("test")) { }
runBlocking { assertThat(CoroutinesUtils.awaitSingleOrNull(Mono.just(value), continuation)).isEqualTo(value)
assertThat(CoroutinesUtils.awaitSingleOrNull(Mono.just(value), continuation)).isEqualTo(value)
}
} }
@Test @Test
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
fun flow() { suspend fun flow() {
val value1 = "foo" val value1 = "foo"
val value2 = "bar" val value2 = "bar"
val values = Flux.just(value1, value2) val values = Flux.just(value1, value2)
val flow = CoroutinesUtils.asFlow(values) as Flow<String> val flow = CoroutinesUtils.asFlow(values) as Flow<String>
runBlocking { assertThat(flow.toList()).containsExactly(value1, value2)
assertThat(flow.toList()).containsExactly(value1, value2)
}
} }
} }

81
spring-context/src/test/kotlin/org/springframework/cache/KotlinCacheReproTests.kt vendored

@ -16,7 +16,6 @@
package org.springframework.cache package org.springframework.cache
import kotlinx.coroutines.runBlocking
import org.assertj.core.api.Assertions.assertThat import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.Test import org.junit.jupiter.api.Test
import org.springframework.beans.testfixture.beans.TestBean import org.springframework.beans.testfixture.beans.TestBean
@ -33,51 +32,47 @@ import org.springframework.context.annotation.Configuration
class KotlinCacheReproTests { class KotlinCacheReproTests {
@Test @Test
fun spr14235AdaptsToSuspendingFunction() { suspend fun spr14235AdaptsToSuspendingFunction() {
runBlocking { val context = AnnotationConfigApplicationContext(
val context = AnnotationConfigApplicationContext( Spr14235Config::class.java,
Spr14235Config::class.java, Spr14235SuspendingService::class.java
Spr14235SuspendingService::class.java )
) val bean = context.getBean(Spr14235SuspendingService::class.java)
val bean = context.getBean(Spr14235SuspendingService::class.java) val cache = context.getBean(CacheManager::class.java).getCache("itemCache")!!
val cache = context.getBean(CacheManager::class.java).getCache("itemCache")!! val tb: TestBean = bean.findById("tb1")
val tb: TestBean = bean.findById("tb1") assertThat(bean.findById("tb1")).isSameAs(tb)
assertThat(bean.findById("tb1")).isSameAs(tb) assertThat(cache["tb1"]!!.get()).isSameAs(tb)
assertThat(cache["tb1"]!!.get()).isSameAs(tb) bean.clear()
bean.clear() val tb2: TestBean = bean.findById("tb1")
val tb2: TestBean = bean.findById("tb1") assertThat(tb2).isNotSameAs(tb)
assertThat(tb2).isNotSameAs(tb) assertThat(cache["tb1"]!!.get()).isSameAs(tb2)
assertThat(cache["tb1"]!!.get()).isSameAs(tb2) bean.clear()
bean.clear() bean.insertItem(tb)
bean.insertItem(tb) assertThat(bean.findById("tb1")).isSameAs(tb)
assertThat(bean.findById("tb1")).isSameAs(tb) assertThat(cache["tb1"]!!.get()).isSameAs(tb)
assertThat(cache["tb1"]!!.get()).isSameAs(tb) context.close()
context.close()
}
} }
@Test @Test
fun spr14235AdaptsToSuspendingFunctionWithSync() { suspend fun spr14235AdaptsToSuspendingFunctionWithSync() {
runBlocking { val context = AnnotationConfigApplicationContext(
val context = AnnotationConfigApplicationContext( Spr14235Config::class.java,
Spr14235Config::class.java, Spr14235SuspendingServiceSync::class.java
Spr14235SuspendingServiceSync::class.java )
) val bean = context.getBean(Spr14235SuspendingServiceSync::class.java)
val bean = context.getBean(Spr14235SuspendingServiceSync::class.java) val cache = context.getBean(CacheManager::class.java).getCache("itemCache")!!
val cache = context.getBean(CacheManager::class.java).getCache("itemCache")!! val tb = bean.findById("tb1")
val tb = bean.findById("tb1") assertThat(bean.findById("tb1")).isSameAs(tb)
assertThat(bean.findById("tb1")).isSameAs(tb) assertThat(cache["tb1"]!!.get()).isSameAs(tb)
assertThat(cache["tb1"]!!.get()).isSameAs(tb) cache.clear()
cache.clear() val tb2 = bean.findById("tb1")
val tb2 = bean.findById("tb1") assertThat(tb2).isNotSameAs(tb)
assertThat(tb2).isNotSameAs(tb) assertThat(cache["tb1"]!!.get()).isSameAs(tb2)
assertThat(cache["tb1"]!!.get()).isSameAs(tb2) cache.clear()
cache.clear() bean.insertItem(tb)
bean.insertItem(tb) assertThat(bean.findById("tb1")).isSameAs(tb)
assertThat(bean.findById("tb1")).isSameAs(tb) assertThat(cache["tb1"]!!.get()).isSameAs(tb)
assertThat(cache["tb1"]!!.get()).isSameAs(tb) context.close()
context.close()
}
} }
@Test @Test

2
spring-context/src/test/kotlin/org/springframework/validation/beanvalidation/MethodValidationKotlinTests.kt

@ -49,7 +49,7 @@ class MethodValidationKotlinTests {
} }
@Test @Test
fun coroutinesParameterValidation() = runBlocking<Unit> { suspend fun coroutinesParameterValidation() {
val bean = MyValidCoroutinesBean() val bean = MyValidCoroutinesBean()
val proxyFactory = ProxyFactory(bean) val proxyFactory = ProxyFactory(bean)
val validator = LocalValidatorFactoryBean() val validator = LocalValidatorFactoryBean()

108
spring-core/src/test/kotlin/org/springframework/core/CoroutinesUtilsTests.kt

@ -18,11 +18,17 @@ package org.springframework.core
import io.micrometer.observation.Observation import io.micrometer.observation.Observation
import io.micrometer.observation.tck.TestObservationRegistry import io.micrometer.observation.tck.TestObservationRegistry
import kotlinx.coroutines.* import kotlinx.coroutines.CoroutineName
import kotlinx.coroutines.Deferred
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.async
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.reactor.awaitSingle import kotlinx.coroutines.reactor.awaitSingle
import kotlinx.coroutines.reactor.awaitSingleOrNull import kotlinx.coroutines.reactor.awaitSingleOrNull
import kotlinx.coroutines.runBlocking
import org.assertj.core.api.Assertions import org.assertj.core.api.Assertions
import org.assertj.core.api.Assertions.assertThat import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.Test import org.junit.jupiter.api.Test
@ -33,8 +39,6 @@ import reactor.core.publisher.Mono
import reactor.test.StepVerifier import reactor.test.StepVerifier
import kotlin.coroutines.Continuation import kotlin.coroutines.Continuation
import kotlin.coroutines.coroutineContext import kotlin.coroutines.coroutineContext
import kotlin.reflect.full.primaryConstructor
import kotlin.reflect.jvm.isAccessible
import kotlin.reflect.jvm.javaMethod import kotlin.reflect.jvm.javaMethod
/** /**
@ -47,8 +51,8 @@ class CoroutinesUtilsTests {
private val observationRegistry = TestObservationRegistry.create() private val observationRegistry = TestObservationRegistry.create()
@Test @Test
fun deferredToMono() { suspend fun deferredToMono() {
runBlocking { coroutineScope {
val deferred: Deferred<String> = async(Dispatchers.IO) { val deferred: Deferred<String> = async(Dispatchers.IO) {
delay(1) delay(1)
"foo" "foo"
@ -62,12 +66,10 @@ class CoroutinesUtilsTests {
} }
@Test @Test
fun monoToDeferred() { suspend fun monoToDeferred() {
runBlocking { val mono = Mono.just("foo")
val mono = Mono.just("foo") val deferred = CoroutinesUtils.monoToDeferred(mono)
val deferred = CoroutinesUtils.monoToDeferred(mono) Assertions.assertThat(deferred.await()).isEqualTo("foo")
Assertions.assertThat(deferred.await()).isEqualTo("foo")
}
} }
@Test @Test
@ -93,12 +95,10 @@ class CoroutinesUtilsTests {
} }
@Test @Test
fun invokeSuspendingFunctionWithNullableParameter() { suspend fun invokeSuspendingFunctionWithNullableParameter() {
val method = CoroutinesUtilsTests::class.java.getDeclaredMethod("suspendingFunctionWithNullable", String::class.java, Continuation::class.java) val method = CoroutinesUtilsTests::class.java.getDeclaredMethod("suspendingFunctionWithNullable", String::class.java, Continuation::class.java)
val mono = CoroutinesUtils.invokeSuspendingFunction(method, this, null, null) as Mono val mono = CoroutinesUtils.invokeSuspendingFunction(method, this, null, null) as Mono
runBlocking { Assertions.assertThat(mono.awaitSingleOrNull()).isNull()
Assertions.assertThat(mono.awaitSingleOrNull()).isNull()
}
} }
@Test @Test
@ -154,23 +154,19 @@ class CoroutinesUtilsTests {
} }
@Test @Test
fun invokeSuspendingFunctionWithNullContinuationParameterAndContext() { suspend fun invokeSuspendingFunctionWithNullContinuationParameterAndContext() {
val method = CoroutinesUtilsTests::class.java.getDeclaredMethod("suspendingFunctionWithContext", String::class.java, Continuation::class.java) val method = CoroutinesUtilsTests::class.java.getDeclaredMethod("suspendingFunctionWithContext", String::class.java, Continuation::class.java)
val context = CoroutineName("name") val context = CoroutineName("name")
val mono = CoroutinesUtils.invokeSuspendingFunction(context, method, this, "foo", null) as Mono val mono = CoroutinesUtils.invokeSuspendingFunction(context, method, this, "foo", null) as Mono
runBlocking { Assertions.assertThat(mono.awaitSingle()).isEqualTo("foo")
Assertions.assertThat(mono.awaitSingle()).isEqualTo("foo")
}
} }
@Test @Test
fun invokeSuspendingFunctionWithoutContinuationParameterAndContext() { suspend fun invokeSuspendingFunctionWithoutContinuationParameterAndContext() {
val method = CoroutinesUtilsTests::class.java.getDeclaredMethod("suspendingFunctionWithContext", String::class.java, Continuation::class.java) val method = CoroutinesUtilsTests::class.java.getDeclaredMethod("suspendingFunctionWithContext", String::class.java, Continuation::class.java)
val context = CoroutineName("name") val context = CoroutineName("name")
val mono = CoroutinesUtils.invokeSuspendingFunction(context, method, this, "foo") as Mono val mono = CoroutinesUtils.invokeSuspendingFunction(context, method, this, "foo") as Mono
runBlocking { Assertions.assertThat(mono.awaitSingle()).isEqualTo("foo")
Assertions.assertThat(mono.awaitSingle()).isEqualTo("foo")
}
} }
@Test @Test
@ -181,57 +177,45 @@ class CoroutinesUtilsTests {
} }
@Test @Test
fun invokeSuspendingFunctionReturningUnit() { suspend fun invokeSuspendingFunctionReturningUnit() {
val method = CoroutinesUtilsTests::class.java.getDeclaredMethod("suspendingUnit", Continuation::class.java) val method = CoroutinesUtilsTests::class.java.getDeclaredMethod("suspendingUnit", Continuation::class.java)
val mono = CoroutinesUtils.invokeSuspendingFunction(method, this) as Mono val mono = CoroutinesUtils.invokeSuspendingFunction(method, this) as Mono
runBlocking { Assertions.assertThat(mono.awaitSingleOrNull()).isNull()
Assertions.assertThat(mono.awaitSingleOrNull()).isNull()
}
} }
@Test @Test
fun invokeSuspendingFunctionReturningNull() { suspend fun invokeSuspendingFunctionReturningNull() {
val method = CoroutinesUtilsTests::class.java.getDeclaredMethod("suspendingNullable", Continuation::class.java) val method = CoroutinesUtilsTests::class.java.getDeclaredMethod("suspendingNullable", Continuation::class.java)
val mono = CoroutinesUtils.invokeSuspendingFunction(method, this) as Mono val mono = CoroutinesUtils.invokeSuspendingFunction(method, this) as Mono
runBlocking { Assertions.assertThat(mono.awaitSingleOrNull()).isNull()
Assertions.assertThat(mono.awaitSingleOrNull()).isNull()
}
} }
@Test @Test
fun invokeSuspendingFunctionWithValueClassParameter() { suspend fun invokeSuspendingFunctionWithValueClassParameter() {
val method = CoroutinesUtilsTests::class.java.declaredMethods.first { it.name.startsWith("suspendingFunctionWithValueClassParameter") } val method = CoroutinesUtilsTests::class.java.declaredMethods.first { it.name.startsWith("suspendingFunctionWithValueClassParameter") }
val mono = CoroutinesUtils.invokeSuspendingFunction(method, this, "foo", null) as Mono val mono = CoroutinesUtils.invokeSuspendingFunction(method, this, "foo", null) as Mono
runBlocking { Assertions.assertThat(mono.awaitSingle()).isEqualTo("foo")
Assertions.assertThat(mono.awaitSingle()).isEqualTo("foo")
}
} }
@Test @Test
fun invokeSuspendingFunctionWithNestedValueClassParameter() { suspend fun invokeSuspendingFunctionWithNestedValueClassParameter() {
val method = CoroutinesUtilsTests::class.java.declaredMethods.first { it.name.startsWith("suspendingFunctionWithNestedValueClassParameter") } val method = CoroutinesUtilsTests::class.java.declaredMethods.first { it.name.startsWith("suspendingFunctionWithNestedValueClassParameter") }
val mono = CoroutinesUtils.invokeSuspendingFunction(method, this, "foo", null) as Mono val mono = CoroutinesUtils.invokeSuspendingFunction(method, this, "foo", null) as Mono
runBlocking { Assertions.assertThat(mono.awaitSingle()).isEqualTo("foo")
Assertions.assertThat(mono.awaitSingle()).isEqualTo("foo")
}
} }
@Test @Test
fun invokeSuspendingFunctionWithValueClassReturnValue() { suspend fun invokeSuspendingFunctionWithValueClassReturnValue() {
val method = CoroutinesUtilsTests::class.java.declaredMethods.first { it.name.startsWith("suspendingFunctionWithValueClassReturnValue") } val method = CoroutinesUtilsTests::class.java.declaredMethods.first { it.name.startsWith("suspendingFunctionWithValueClassReturnValue") }
val mono = CoroutinesUtils.invokeSuspendingFunction(method, this, null) as Mono val mono = CoroutinesUtils.invokeSuspendingFunction(method, this, null) as Mono
runBlocking { Assertions.assertThat(mono.awaitSingle()).isEqualTo(ValueClass("foo"))
Assertions.assertThat(mono.awaitSingle()).isEqualTo(ValueClass("foo"))
}
} }
@Test @Test
fun invokeSuspendingFunctionWithResultOfUnitReturnValue() { suspend fun invokeSuspendingFunctionWithResultOfUnitReturnValue() {
val method = CoroutinesUtilsTests::class.java.declaredMethods.first { it.name.startsWith("suspendingFunctionWithResultOfUnitReturnValue") } val method = CoroutinesUtilsTests::class.java.declaredMethods.first { it.name.startsWith("suspendingFunctionWithResultOfUnitReturnValue") }
val mono = CoroutinesUtils.invokeSuspendingFunction(method, this, null) as Mono val mono = CoroutinesUtils.invokeSuspendingFunction(method, this, null) as Mono
runBlocking { Assertions.assertThat(mono.awaitSingle()).isEqualTo(Result.success(Unit))
Assertions.assertThat(mono.awaitSingle()).isEqualTo(Result.success(Unit))
}
} }
@Test @Test
@ -246,51 +230,41 @@ class CoroutinesUtilsTests {
} }
@Test @Test
fun invokeSuspendingFunctionWithNullableValueClassParameter() { suspend fun invokeSuspendingFunctionWithNullableValueClassParameter() {
val method = CoroutinesUtilsTests::class.java.declaredMethods.first { it.name.startsWith("suspendingFunctionWithNullableValueClass") } val method = CoroutinesUtilsTests::class.java.declaredMethods.first { it.name.startsWith("suspendingFunctionWithNullableValueClass") }
val mono = CoroutinesUtils.invokeSuspendingFunction(method, this, null, null) as Mono val mono = CoroutinesUtils.invokeSuspendingFunction(method, this, null, null) as Mono
runBlocking { Assertions.assertThat(mono.awaitSingleOrNull()).isNull()
Assertions.assertThat(mono.awaitSingleOrNull()).isNull()
}
} }
@Test @Test
fun invokeSuspendingFunctionWithValueClassWithPrivateConstructorParameter() { suspend fun invokeSuspendingFunctionWithValueClassWithPrivateConstructorParameter() {
val method = CoroutinesUtilsTests::class.java.declaredMethods.first { it.name.startsWith("suspendingFunctionWithValueClassWithPrivateConstructor") } val method = CoroutinesUtilsTests::class.java.declaredMethods.first { it.name.startsWith("suspendingFunctionWithValueClassWithPrivateConstructor") }
val mono = CoroutinesUtils.invokeSuspendingFunction(method, this, "foo", null) as Mono val mono = CoroutinesUtils.invokeSuspendingFunction(method, this, "foo", null) as Mono
runBlocking { Assertions.assertThat(mono.awaitSingleOrNull()).isEqualTo("foo")
Assertions.assertThat(mono.awaitSingleOrNull()).isEqualTo("foo")
}
} }
@Test @Test
fun invokeSuspendingFunctionWithExtension() { suspend fun invokeSuspendingFunctionWithExtension() {
val method = CoroutinesUtilsTests::class.java.getDeclaredMethod("suspendingFunctionWithExtension", val method = CoroutinesUtilsTests::class.java.getDeclaredMethod("suspendingFunctionWithExtension",
CustomException::class.java, Continuation::class.java) CustomException::class.java, Continuation::class.java)
val mono = CoroutinesUtils.invokeSuspendingFunction(method, this, CustomException("foo")) as Mono val mono = CoroutinesUtils.invokeSuspendingFunction(method, this, CustomException("foo")) as Mono
runBlocking { Assertions.assertThat(mono.awaitSingleOrNull()).isEqualTo("foo")
Assertions.assertThat(mono.awaitSingleOrNull()).isEqualTo("foo")
}
} }
@Test @Test
fun invokeSuspendingFunctionWithExtensionAndParameter() { suspend fun invokeSuspendingFunctionWithExtensionAndParameter() {
val method = CoroutinesUtilsTests::class.java.getDeclaredMethod("suspendingFunctionWithExtensionAndParameter", val method = CoroutinesUtilsTests::class.java.getDeclaredMethod("suspendingFunctionWithExtensionAndParameter",
CustomException::class.java, Int::class.java, Continuation::class.java) CustomException::class.java, Int::class.java, Continuation::class.java)
val mono = CoroutinesUtils.invokeSuspendingFunction(method, this, CustomException("foo"), 20) as Mono val mono = CoroutinesUtils.invokeSuspendingFunction(method, this, CustomException("foo"), 20) as Mono
runBlocking { Assertions.assertThat(mono.awaitSingleOrNull()).isEqualTo("foo-20")
Assertions.assertThat(mono.awaitSingleOrNull()).isEqualTo("foo-20")
}
} }
@Test @Test
fun invokeSuspendingFunctionWithGenericParameter() { suspend fun invokeSuspendingFunctionWithGenericParameter() {
val method = GenericController::class.java.declaredMethods.first { it.name.startsWith("handle") } val method = GenericController::class.java.declaredMethods.first { it.name.startsWith("handle") }
val horse = Animal("horse") val horse = Animal("horse")
val mono = CoroutinesUtils.invokeSuspendingFunction(method, AnimalController(), horse, null) as Mono val mono = CoroutinesUtils.invokeSuspendingFunction(method, AnimalController(), horse, null) as Mono
runBlocking { Assertions.assertThat(mono.awaitSingle()).isEqualTo(horse.name)
Assertions.assertThat(mono.awaitSingle()).isEqualTo(horse.name)
}
} }
@Test @Test

9
spring-core/src/test/kotlin/org/springframework/core/ReactiveAdapterRegistryKotlinTests.kt

@ -23,7 +23,6 @@ import kotlinx.coroutines.async
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flow import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.toList import kotlinx.coroutines.flow.toList
import kotlinx.coroutines.runBlocking
import org.assertj.core.api.Assertions.assertThat import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.Test import org.junit.jupiter.api.Test
import org.reactivestreams.Publisher import org.reactivestreams.Publisher
@ -52,11 +51,11 @@ class ReactiveAdapterRegistryKotlinTests {
} }
@Test @Test
fun publisherToDeferred() { suspend fun publisherToDeferred() {
val source = Mono.just(1) val source = Mono.just(1)
val target = getAdapter(Deferred::class).fromPublisher(source) val target = getAdapter(Deferred::class).fromPublisher(source)
assertThat(target).isInstanceOf(Deferred::class.java) assertThat(target).isInstanceOf(Deferred::class.java)
assertThat(runBlocking { (target as Deferred<*>).await() }).isEqualTo(1) assertThat((target as Deferred<*>).await()).isEqualTo(1)
} }
@Test @Test
@ -76,11 +75,11 @@ class ReactiveAdapterRegistryKotlinTests {
} }
@Test @Test
fun publisherToFlow() { suspend fun publisherToFlow() {
val source = Flux.just(1, 2, 3) val source = Flux.just(1, 2, 3)
val target = getAdapter(Flow::class).fromPublisher(source) val target = getAdapter(Flow::class).fromPublisher(source)
assertThat(target).isInstanceOf(Flow::class.java) assertThat(target).isInstanceOf(Flow::class.java)
assertThat(runBlocking { (target as Flow<*>).toList() }).contains(1, 2, 3) assertThat((target as Flow<*>).toList()).contains(1, 2, 3)
} }
private fun getAdapter(reactiveType: KClass<*>): ReactiveAdapter { private fun getAdapter(reactiveType: KClass<*>): ReactiveAdapter {

51
spring-messaging/src/test/kotlin/org/springframework/messaging/rsocket/RSocketRequesterExtensionsTests.kt

@ -20,7 +20,6 @@ import io.mockk.every
import io.mockk.mockk import io.mockk.mockk
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.toList import kotlinx.coroutines.flow.toList
import kotlinx.coroutines.runBlocking
import org.assertj.core.api.Assertions.assertThat import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.Test import org.junit.jupiter.api.Test
import org.reactivestreams.Publisher import org.reactivestreams.Publisher
@ -40,36 +39,30 @@ class RSocketRequesterExtensionsTests {
@Test @Test
@Suppress("DEPRECATION") @Suppress("DEPRECATION")
fun connectAndAwait() { suspend fun connectAndAwait() {
val requester = mockk<RSocketRequester>() val requester = mockk<RSocketRequester>()
val builder = mockk<RSocketRequester.Builder>() val builder = mockk<RSocketRequester.Builder>()
every { builder.connect(any()) } returns Mono.just(requester) every { builder.connect(any()) } returns Mono.just(requester)
runBlocking { assertThat(builder.connectAndAwait(mockk())).isEqualTo(requester)
assertThat(builder.connectAndAwait(mockk())).isEqualTo(requester)
}
} }
@Test @Test
@Suppress("DEPRECATION") @Suppress("DEPRECATION")
fun connectTcpAndAwait() { suspend fun connectTcpAndAwait() {
val host = "127.0.0.1" val host = "127.0.0.1"
val requester = mockk<RSocketRequester>() val requester = mockk<RSocketRequester>()
val builder = mockk<RSocketRequester.Builder>() val builder = mockk<RSocketRequester.Builder>()
every { builder.connectTcp(host, any()) } returns Mono.just(requester) every { builder.connectTcp(host, any()) } returns Mono.just(requester)
runBlocking { assertThat(builder.connectTcpAndAwait(host, 0)).isEqualTo(requester)
assertThat(builder.connectTcpAndAwait(host, 0)).isEqualTo(requester)
}
} }
@Test @Test
@Suppress("DEPRECATION") @Suppress("DEPRECATION")
fun connectWebSocketAndAwait() { suspend fun connectWebSocketAndAwait() {
val requester = mockk<RSocketRequester>() val requester = mockk<RSocketRequester>()
val builder = mockk<RSocketRequester.Builder>() val builder = mockk<RSocketRequester.Builder>()
every { builder.connectWebSocket(any()) } returns Mono.just(requester) every { builder.connectWebSocket(any()) } returns Mono.just(requester)
runBlocking { assertThat(builder.connectWebSocketAndAwait(mockk())).isEqualTo(requester)
assertThat(builder.connectWebSocketAndAwait(mockk())).isEqualTo(requester)
}
} }
@Test @Test
@ -104,57 +97,45 @@ class RSocketRequesterExtensionsTests {
} }
@Test @Test
fun sendAndAwait() { suspend fun sendAndAwait() {
val retrieveSpec = mockk<RSocketRequester.RetrieveSpec>() val retrieveSpec = mockk<RSocketRequester.RetrieveSpec>()
every { retrieveSpec.send() } returns Mono.empty() every { retrieveSpec.send() } returns Mono.empty()
runBlocking { retrieveSpec.sendAndAwait()
retrieveSpec.sendAndAwait()
}
} }
@Test @Test
fun retrieveAndAwait() { suspend fun retrieveAndAwait() {
val response = "foo" val response = "foo"
val retrieveSpec = mockk<RSocketRequester.RetrieveSpec>() val retrieveSpec = mockk<RSocketRequester.RetrieveSpec>()
every { retrieveSpec.retrieveMono(match<ParameterizedTypeReference<*>>(stringTypeRefMatcher)) } returns Mono.just("foo") every { retrieveSpec.retrieveMono(match<ParameterizedTypeReference<*>>(stringTypeRefMatcher)) } returns Mono.just("foo")
runBlocking { assertThat(retrieveSpec.retrieveAndAwait<String>()).isEqualTo(response)
assertThat(retrieveSpec.retrieveAndAwait<String>()).isEqualTo(response)
}
} }
@Test @Test
fun retrieveAndAwaitOrNull() { suspend fun retrieveAndAwaitOrNull() {
val retrieveSpec = mockk<RSocketRequester.RetrieveSpec>() val retrieveSpec = mockk<RSocketRequester.RetrieveSpec>()
every { retrieveSpec.retrieveMono(match<ParameterizedTypeReference<*>>(stringTypeRefMatcher)) } returns Mono.empty() every { retrieveSpec.retrieveMono(match<ParameterizedTypeReference<*>>(stringTypeRefMatcher)) } returns Mono.empty()
runBlocking { assertThat(retrieveSpec.retrieveAndAwaitOrNull<String>()).isNull()
assertThat(retrieveSpec.retrieveAndAwaitOrNull<String>()).isNull()
}
} }
@Test @Test
fun retrieveFlow() { suspend fun retrieveFlow() {
val retrieveSpec = mockk<RSocketRequester.RetrieveSpec>() val retrieveSpec = mockk<RSocketRequester.RetrieveSpec>()
every { retrieveSpec.retrieveFlux(match<ParameterizedTypeReference<*>>(stringTypeRefMatcher)) } returns Flux.just("foo", "bar") every { retrieveSpec.retrieveFlux(match<ParameterizedTypeReference<*>>(stringTypeRefMatcher)) } returns Flux.just("foo", "bar")
runBlocking { assertThat(retrieveSpec.retrieveFlow<String>().toList()).contains("foo", "bar")
assertThat(retrieveSpec.retrieveFlow<String>().toList()).contains("foo", "bar")
}
} }
@Test @Test
fun retrieveMono() { fun retrieveMono() {
val retrieveSpec = mockk<RSocketRequester.RetrieveSpec>() val retrieveSpec = mockk<RSocketRequester.RetrieveSpec>()
every { retrieveSpec.retrieveMono(match<ParameterizedTypeReference<*>>(stringTypeRefMatcher)) } returns Mono.just("foo") every { retrieveSpec.retrieveMono(match<ParameterizedTypeReference<*>>(stringTypeRefMatcher)) } returns Mono.just("foo")
runBlocking { assertThat(retrieveSpec.retrieveMono<String>().block()).isEqualTo("foo")
assertThat(retrieveSpec.retrieveMono<String>().block()).isEqualTo("foo")
}
} }
@Test @Test
fun retrieveFlux() { fun retrieveFlux() {
val retrieveSpec = mockk<RSocketRequester.RetrieveSpec>() val retrieveSpec = mockk<RSocketRequester.RetrieveSpec>()
every { retrieveSpec.retrieveFlux(match<ParameterizedTypeReference<*>>(stringTypeRefMatcher)) } returns Flux.just("foo", "bar") every { retrieveSpec.retrieveFlux(match<ParameterizedTypeReference<*>>(stringTypeRefMatcher)) } returns Flux.just("foo", "bar")
runBlocking { assertThat(retrieveSpec.retrieveFlux<String>().collectList().block()).contains("foo", "bar")
assertThat(retrieveSpec.retrieveFlux<String>().collectList().block()).contains("foo", "bar")
}
} }
} }

11
spring-messaging/src/test/kotlin/org/springframework/messaging/rsocket/service/RSocketServiceMethodKotlinTests.kt

@ -22,7 +22,6 @@ import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.toList import kotlinx.coroutines.flow.toList
import kotlinx.coroutines.reactive.asFlow import kotlinx.coroutines.reactive.asFlow
import kotlinx.coroutines.runBlocking
import org.assertj.core.api.Assertions.assertThat import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test import org.junit.jupiter.api.Test
@ -53,7 +52,7 @@ class RSocketServiceMethodKotlinTests {
} }
@Test @Test
fun fireAndForget(): Unit = runBlocking { suspend fun fireAndForget() {
val service = proxyFactory.createClient(SuspendingFunctionsService::class.java) val service = proxyFactory.createClient(SuspendingFunctionsService::class.java)
val requestPayload = "request" val requestPayload = "request"
@ -65,7 +64,7 @@ class RSocketServiceMethodKotlinTests {
} }
@Test @Test
fun requestResponse(): Unit = runBlocking { suspend fun requestResponse() {
val service = proxyFactory.createClient(SuspendingFunctionsService::class.java) val service = proxyFactory.createClient(SuspendingFunctionsService::class.java)
val requestPayload = "request" val requestPayload = "request"
@ -80,7 +79,7 @@ class RSocketServiceMethodKotlinTests {
} }
@Test @Test
fun requestStream(): Unit = runBlocking { suspend fun requestStream() {
val service = proxyFactory.createClient(SuspendingFunctionsService::class.java) val service = proxyFactory.createClient(SuspendingFunctionsService::class.java)
val requestPayload = "request" val requestPayload = "request"
@ -97,7 +96,7 @@ class RSocketServiceMethodKotlinTests {
} }
@Test @Test
fun nonSuspendingRequestStream(): Unit = runBlocking { suspend fun nonSuspendingRequestStream() {
val service = proxyFactory.createClient(NonSuspendingFunctionsService::class.java) val service = proxyFactory.createClient(NonSuspendingFunctionsService::class.java)
val requestPayload = "request" val requestPayload = "request"
@ -114,7 +113,7 @@ class RSocketServiceMethodKotlinTests {
} }
@Test @Test
fun requestChannel(): Unit = runBlocking { suspend fun requestChannel() {
val service = proxyFactory.createClient(SuspendingFunctionsService::class.java) val service = proxyFactory.createClient(SuspendingFunctionsService::class.java)
val requestPayload1 = "request1" val requestPayload1 = "request1"

33
spring-r2dbc/src/test/kotlin/org/springframework/r2dbc/core/DatabaseClientExtensionsTests.kt

@ -20,7 +20,6 @@ import io.mockk.every
import io.mockk.mockk import io.mockk.mockk
import io.mockk.verify import io.mockk.verify
import io.r2dbc.spi.Parameters import io.r2dbc.spi.Parameters
import kotlinx.coroutines.runBlocking
import org.junit.jupiter.api.Test import org.junit.jupiter.api.Test
import reactor.core.publisher.Mono import reactor.core.publisher.Mono
@ -37,11 +36,7 @@ class DatabaseClientExtensionsTests {
fun bindByIndexShouldBindValue() { fun bindByIndexShouldBindValue() {
val spec = mockk<DatabaseClient.GenericExecuteSpec>() val spec = mockk<DatabaseClient.GenericExecuteSpec>()
every { spec.bind(eq(0), any()) } returns spec every { spec.bind(eq(0), any()) } returns spec
spec.bind<String>(0, "foo")
runBlocking {
spec.bind<String>(0, "foo")
}
verify { verify {
spec.bind(0, Parameters.`in`("foo")) spec.bind(0, Parameters.`in`("foo"))
} }
@ -51,11 +46,7 @@ class DatabaseClientExtensionsTests {
fun bindByIndexShouldBindNull() { fun bindByIndexShouldBindNull() {
val spec = mockk<DatabaseClient.GenericExecuteSpec>() val spec = mockk<DatabaseClient.GenericExecuteSpec>()
every { spec.bind(eq(0), any()) } returns spec every { spec.bind(eq(0), any()) } returns spec
spec.bind<String>(0, null)
runBlocking {
spec.bind<String>(0, null)
}
verify { verify {
spec.bind(0, Parameters.`in`(String::class.java)) spec.bind(0, Parameters.`in`(String::class.java))
} }
@ -65,11 +56,7 @@ class DatabaseClientExtensionsTests {
fun bindByNameShouldBindValue() { fun bindByNameShouldBindValue() {
val spec = mockk<DatabaseClient.GenericExecuteSpec>() val spec = mockk<DatabaseClient.GenericExecuteSpec>()
every { spec.bind(eq("field"), any()) } returns spec every { spec.bind(eq("field"), any()) } returns spec
spec.bind<String>("field", "foo")
runBlocking {
spec.bind<String>("field", "foo")
}
verify { verify {
spec.bind("field", Parameters.`in`("foo")) spec.bind("field", Parameters.`in`("foo"))
} }
@ -79,25 +66,17 @@ class DatabaseClientExtensionsTests {
fun bindByNameShouldBindNull() { fun bindByNameShouldBindNull() {
val spec = mockk<DatabaseClient.GenericExecuteSpec>() val spec = mockk<DatabaseClient.GenericExecuteSpec>()
every { spec.bind(eq("field"), any()) } returns spec every { spec.bind(eq("field"), any()) } returns spec
spec.bind<String>("field", null)
runBlocking {
spec.bind<String>("field", null)
}
verify { verify {
spec.bind("field", Parameters.`in`(String::class.java)) spec.bind("field", Parameters.`in`(String::class.java))
} }
} }
@Test @Test
fun genericExecuteSpecAwait() { suspend fun genericExecuteSpecAwait() {
val spec = mockk<DatabaseClient.GenericExecuteSpec>() val spec = mockk<DatabaseClient.GenericExecuteSpec>()
every { spec.then() } returns Mono.empty() every { spec.then() } returns Mono.empty()
spec.await()
runBlocking {
spec.await()
}
verify { verify {
spec.then() spec.then()
} }

60
spring-r2dbc/src/test/kotlin/org/springframework/r2dbc/core/RowsFetchSpecExtensionsTests.kt

@ -37,14 +37,10 @@ import reactor.core.publisher.Mono
class RowsFetchSpecExtensionsTests { class RowsFetchSpecExtensionsTests {
@Test @Test
fun awaitOneWithValue() { suspend fun awaitOneWithValue() {
val spec = mockk<RowsFetchSpec<String>>() val spec = mockk<RowsFetchSpec<String>>()
every { spec.one() } returns Mono.just("foo") every { spec.one() } returns Mono.just("foo")
assertThat(spec.awaitOne()).isEqualTo("foo")
runBlocking {
assertThat(spec.awaitOne()).isEqualTo("foo")
}
verify { verify {
spec.one() spec.one()
} }
@ -54,53 +50,39 @@ class RowsFetchSpecExtensionsTests {
fun awaitOneWithNull() { fun awaitOneWithNull() {
val spec = mockk<RowsFetchSpec<String>>() val spec = mockk<RowsFetchSpec<String>>()
every { spec.one() } returns Mono.empty() every { spec.one() } returns Mono.empty()
assertThatExceptionOfType(EmptyResultDataAccessException::class.java).isThrownBy { assertThatExceptionOfType(EmptyResultDataAccessException::class.java).isThrownBy {
runBlocking { spec.awaitOne() } runBlocking { spec.awaitOne() }
} }
verify { verify {
spec.one() spec.one()
} }
} }
@Test @Test
fun awaitOneOrNullWithValue() { suspend fun awaitOneOrNullWithValue() {
val spec = mockk<RowsFetchSpec<String>>() val spec = mockk<RowsFetchSpec<String>>()
every { spec.one() } returns Mono.just("foo") every { spec.one() } returns Mono.just("foo")
assertThat(spec.awaitOneOrNull()).isEqualTo("foo")
runBlocking {
assertThat(spec.awaitOneOrNull()).isEqualTo("foo")
}
verify { verify {
spec.one() spec.one()
} }
} }
@Test @Test
fun awaitOneOrNullWithNull() { suspend fun awaitOneOrNullWithNull() {
val spec = mockk<RowsFetchSpec<String>>() val spec = mockk<RowsFetchSpec<String>>()
every { spec.one() } returns Mono.empty() every { spec.one() } returns Mono.empty()
assertThat(spec.awaitOneOrNull()).isNull()
runBlocking {
assertThat(spec.awaitOneOrNull()).isNull()
}
verify { verify {
spec.one() spec.one()
} }
} }
@Test @Test
fun awaitFirstWithValue() { suspend fun awaitFirstWithValue() {
val spec = mockk<RowsFetchSpec<String>>() val spec = mockk<RowsFetchSpec<String>>()
every { spec.first() } returns Mono.just("foo") every { spec.first() } returns Mono.just("foo")
assertThat(spec.awaitSingle()).isEqualTo("foo")
runBlocking {
assertThat(spec.awaitSingle()).isEqualTo("foo")
}
verify { verify {
spec.first() spec.first()
} }
@ -110,39 +92,29 @@ class RowsFetchSpecExtensionsTests {
fun awaitFirstWithNull() { fun awaitFirstWithNull() {
val spec = mockk<RowsFetchSpec<String>>() val spec = mockk<RowsFetchSpec<String>>()
every { spec.first() } returns Mono.empty() every { spec.first() } returns Mono.empty()
assertThatExceptionOfType(EmptyResultDataAccessException::class.java).isThrownBy { assertThatExceptionOfType(EmptyResultDataAccessException::class.java).isThrownBy {
runBlocking { spec.awaitSingle() } runBlocking { spec.awaitSingle() }
} }
verify { verify {
spec.first() spec.first()
} }
} }
@Test @Test
fun awaitSingleOrNullWithValue() { suspend fun awaitSingleOrNullWithValue() {
val spec = mockk<RowsFetchSpec<String>>() val spec = mockk<RowsFetchSpec<String>>()
every { spec.first() } returns Mono.just("foo") every { spec.first() } returns Mono.just("foo")
assertThat(spec.awaitSingleOrNull()).isEqualTo("foo")
runBlocking {
assertThat(spec.awaitSingleOrNull()).isEqualTo("foo")
}
verify { verify {
spec.first() spec.first()
} }
} }
@Test @Test
fun awaitSingleOrNullWithNull() { suspend fun awaitSingleOrNullWithNull() {
val spec = mockk<RowsFetchSpec<String>>() val spec = mockk<RowsFetchSpec<String>>()
every { spec.first() } returns Mono.empty() every { spec.first() } returns Mono.empty()
assertThat(spec.awaitSingleOrNull()).isNull()
runBlocking {
assertThat(spec.awaitSingleOrNull()).isNull()
}
verify { verify {
spec.first() spec.first()
} }
@ -150,14 +122,10 @@ class RowsFetchSpecExtensionsTests {
@Test @Test
@ExperimentalCoroutinesApi @ExperimentalCoroutinesApi
fun allAsFlow() { suspend fun allAsFlow() {
val spec = mockk<RowsFetchSpec<String>>() val spec = mockk<RowsFetchSpec<String>>()
every { spec.all() } returns Flux.just("foo", "bar", "baz") every { spec.all() } returns Flux.just("foo", "bar", "baz")
assertThat(spec.flow().toList()).contains("foo", "bar", "baz")
runBlocking {
assertThat(spec.flow().toList()).contains("foo", "bar", "baz")
}
verify { verify {
spec.all() spec.all()
} }

9
spring-r2dbc/src/test/kotlin/org/springframework/r2dbc/core/UpdatedRowsFetchSpecExtensionsTests.kt

@ -19,7 +19,6 @@ package org.springframework.r2dbc.core
import io.mockk.every import io.mockk.every
import io.mockk.mockk import io.mockk.mockk
import io.mockk.verify import io.mockk.verify
import kotlinx.coroutines.runBlocking
import org.assertj.core.api.Assertions.assertThat import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.Test import org.junit.jupiter.api.Test
import reactor.core.publisher.Mono import reactor.core.publisher.Mono
@ -32,14 +31,10 @@ import reactor.core.publisher.Mono
class UpdatedRowsFetchSpecExtensionsTests { class UpdatedRowsFetchSpecExtensionsTests {
@Test @Test
fun awaitRowsUpdatedWithValue() { suspend fun awaitRowsUpdatedWithValue() {
val spec = mockk<UpdatedRowsFetchSpec>() val spec = mockk<UpdatedRowsFetchSpec>()
every { spec.rowsUpdated() } returns Mono.just(42) every { spec.rowsUpdated() } returns Mono.just(42)
assertThat(spec.awaitRowsUpdated()).isEqualTo(42)
runBlocking {
assertThat(spec.awaitRowsUpdated()).isEqualTo(42)
}
verify { verify {
spec.rowsUpdated() spec.rowsUpdated()
} }

32
spring-tx/src/test/kotlin/org/springframework/transaction/annotation/CoroutinesAnnotationTransactionInterceptorTests.kt

@ -42,14 +42,12 @@ class CoroutinesAnnotationTransactionInterceptorTests {
private val source = AnnotationTransactionAttributeSource() private val source = AnnotationTransactionAttributeSource()
@Test @Test
fun suspendingNoValueSuccess() { suspend fun suspendingNoValueSuccess() {
val proxyFactory = ProxyFactory() val proxyFactory = ProxyFactory()
proxyFactory.setTarget(TestWithCoroutines()) proxyFactory.setTarget(TestWithCoroutines())
proxyFactory.addAdvice(TransactionInterceptor(rtm, source)) proxyFactory.addAdvice(TransactionInterceptor(rtm, source))
val proxy = proxyFactory.proxy as TestWithCoroutines val proxy = proxyFactory.proxy as TestWithCoroutines
runBlocking { proxy.suspendingNoValueSuccess()
proxy.suspendingNoValueSuccess()
}
assertReactiveGetTransactionAndCommitCount(1) assertReactiveGetTransactionAndCommitCount(1)
} }
@ -68,14 +66,12 @@ class CoroutinesAnnotationTransactionInterceptorTests {
} }
@Test @Test
fun suspendingValueSuccess() { suspend fun suspendingValueSuccess() {
val proxyFactory = ProxyFactory() val proxyFactory = ProxyFactory()
proxyFactory.setTarget(TestWithCoroutines()) proxyFactory.setTarget(TestWithCoroutines())
proxyFactory.addAdvice(TransactionInterceptor(rtm, source)) proxyFactory.addAdvice(TransactionInterceptor(rtm, source))
val proxy = proxyFactory.proxy as TestWithCoroutines val proxy = proxyFactory.proxy as TestWithCoroutines
runBlocking { assertThat(proxy.suspendingValueSuccess()).isEqualTo("foo")
assertThat(proxy.suspendingValueSuccess()).isEqualTo("foo")
}
assertReactiveGetTransactionAndCommitCount(1) assertReactiveGetTransactionAndCommitCount(1)
} }
@ -94,39 +90,33 @@ class CoroutinesAnnotationTransactionInterceptorTests {
} }
@Test @Test
fun suspendingFlowSuccess() { suspend fun suspendingFlowSuccess() {
val proxyFactory = ProxyFactory() val proxyFactory = ProxyFactory()
proxyFactory.setTarget(TestWithCoroutines()) proxyFactory.setTarget(TestWithCoroutines())
proxyFactory.addAdvice(TransactionInterceptor(rtm, source)) proxyFactory.addAdvice(TransactionInterceptor(rtm, source))
val proxy = proxyFactory.proxy as TestWithCoroutines val proxy = proxyFactory.proxy as TestWithCoroutines
runBlocking { assertThat(proxy.suspendingFlowSuccess().toList()).containsExactly("foo", "foo")
assertThat(proxy.suspendingFlowSuccess().toList()).containsExactly("foo", "foo")
}
assertReactiveGetTransactionAndCommitCount(1) assertReactiveGetTransactionAndCommitCount(1)
} }
@Test @Test
fun flowSuccess() { suspend fun flowSuccess() {
val proxyFactory = ProxyFactory() val proxyFactory = ProxyFactory()
proxyFactory.setTarget(TestWithCoroutines()) proxyFactory.setTarget(TestWithCoroutines())
proxyFactory.addAdvice(TransactionInterceptor(rtm, source)) proxyFactory.addAdvice(TransactionInterceptor(rtm, source))
val proxy = proxyFactory.proxy as TestWithCoroutines val proxy = proxyFactory.proxy as TestWithCoroutines
runBlocking { assertThat(proxy.flowSuccess().toList()).containsExactly("foo", "foo")
assertThat(proxy.flowSuccess().toList()).containsExactly("foo", "foo")
}
assertReactiveGetTransactionAndCommitCount(1) assertReactiveGetTransactionAndCommitCount(1)
} }
@Test @Test
fun suspendingValueSuccessWithContext() { suspend fun suspendingValueSuccessWithContext() {
val proxyFactory = ProxyFactory() val proxyFactory = ProxyFactory()
proxyFactory.setTarget(TestWithCoroutines()) proxyFactory.setTarget(TestWithCoroutines())
proxyFactory.addAdvice(TransactionInterceptor(rtm, source)) proxyFactory.addAdvice(TransactionInterceptor(rtm, source))
val proxy = proxyFactory.proxy as TestWithCoroutines val proxy = proxyFactory.proxy as TestWithCoroutines
assertThat(runBlocking { assertThat(withExampleContext("context") {
withExampleContext("context") { proxy.suspendingValueSuccessWithContext()
proxy.suspendingValueSuccessWithContext()
}
}).isEqualTo("context") }).isEqualTo("context")
assertReactiveGetTransactionAndCommitCount(1) assertReactiveGetTransactionAndCommitCount(1)
} }

57
spring-tx/src/test/kotlin/org/springframework/transaction/interceptor/AbstractCoroutinesTransactionAspectTests.kt

@ -19,6 +19,7 @@ package org.springframework.transaction.interceptor
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
import kotlinx.coroutines.runBlocking import kotlinx.coroutines.runBlocking
import org.assertj.core.api.Assertions.assertThat import org.assertj.core.api.Assertions.assertThat
import org.assertj.core.api.Assertions.assertThatExceptionOfType
import org.assertj.core.api.Fail import org.assertj.core.api.Fail
import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test import org.junit.jupiter.api.Test
@ -53,7 +54,7 @@ abstract class AbstractCoroutinesTransactionAspectTests {
} }
@Test @Test
fun noTransaction() { suspend fun noTransaction() {
val rtm = Mockito.mock(ReactiveTransactionManager::class.java) val rtm = Mockito.mock(ReactiveTransactionManager::class.java)
val tb = DefaultTestBean() val tb = DefaultTestBean()
val tas: TransactionAttributeSource = MapTransactionAttributeSource() val tas: TransactionAttributeSource = MapTransactionAttributeSource()
@ -63,9 +64,7 @@ abstract class AbstractCoroutinesTransactionAspectTests {
// and transaction attribute source // and transaction attribute source
val itb = advised(tb, rtm, tas) as TestBean val itb = advised(tb, rtm, tas) as TestBean
checkReactiveTransaction(false) checkReactiveTransaction(false)
runBlocking { itb.getName()
itb.getName()
}
checkReactiveTransaction(false) checkReactiveTransaction(false)
// expect no calls // expect no calls
@ -76,7 +75,7 @@ abstract class AbstractCoroutinesTransactionAspectTests {
* Check that a transaction is created and committed. * Check that a transaction is created and committed.
*/ */
@Test @Test
fun transactionShouldSucceed() { suspend fun transactionShouldSucceed() {
val txatt: TransactionAttribute = DefaultTransactionAttribute() val txatt: TransactionAttribute = DefaultTransactionAttribute()
val tas = MapTransactionAttributeSource() val tas = MapTransactionAttributeSource()
tas.register(getNameMethod!!, txatt) tas.register(getNameMethod!!, txatt)
@ -87,9 +86,7 @@ abstract class AbstractCoroutinesTransactionAspectTests {
given(rtm.commit(status)).willReturn(Mono.empty()) given(rtm.commit(status)).willReturn(Mono.empty())
val tb = DefaultTestBean() val tb = DefaultTestBean()
val itb = advised(tb, rtm, tas) as TestBean val itb = advised(tb, rtm, tas) as TestBean
runBlocking { itb.getName()
itb.getName()
}
Mockito.verify(rtm).commit(status) Mockito.verify(rtm).commit(status)
} }
@ -97,7 +94,7 @@ abstract class AbstractCoroutinesTransactionAspectTests {
* Check that two transactions are created and committed. * Check that two transactions are created and committed.
*/ */
@Test @Test
fun twoTransactionsShouldSucceed() { suspend fun twoTransactionsShouldSucceed() {
val txatt: TransactionAttribute = DefaultTransactionAttribute() val txatt: TransactionAttribute = DefaultTransactionAttribute()
val tas1 = MapTransactionAttributeSource() val tas1 = MapTransactionAttributeSource()
tas1.register(getNameMethod!!, txatt) tas1.register(getNameMethod!!, txatt)
@ -110,10 +107,8 @@ abstract class AbstractCoroutinesTransactionAspectTests {
given(rtm.commit(status)).willReturn(Mono.empty()) given(rtm.commit(status)).willReturn(Mono.empty())
val tb = DefaultTestBean() val tb = DefaultTestBean()
val itb = advised(tb, rtm, arrayOf(tas1, tas2)) as TestBean val itb = advised(tb, rtm, arrayOf(tas1, tas2)) as TestBean
runBlocking { itb.getName()
itb.getName() itb.setName("myName")
itb.setName("myName")
}
Mockito.verify(rtm, Mockito.times(2)).commit(status) Mockito.verify(rtm, Mockito.times(2)).commit(status)
} }
@ -121,7 +116,7 @@ abstract class AbstractCoroutinesTransactionAspectTests {
* Check that a transaction is created and committed. * Check that a transaction is created and committed.
*/ */
@Test @Test
fun transactionShouldSucceedWithNotNew() { suspend fun transactionShouldSucceedWithNotNew() {
val txatt: TransactionAttribute = DefaultTransactionAttribute() val txatt: TransactionAttribute = DefaultTransactionAttribute()
val tas = MapTransactionAttributeSource() val tas = MapTransactionAttributeSource()
tas.register(getNameMethod!!, txatt) tas.register(getNameMethod!!, txatt)
@ -132,9 +127,7 @@ abstract class AbstractCoroutinesTransactionAspectTests {
given(rtm.commit(status)).willReturn(Mono.empty()) given(rtm.commit(status)).willReturn(Mono.empty())
val tb = DefaultTestBean() val tb = DefaultTestBean()
val itb = advised(tb, rtm, tas) as TestBean val itb = advised(tb, rtm, tas) as TestBean
runBlocking { itb.getName()
itb.getName()
}
Mockito.verify(rtm).commit(status) Mockito.verify(rtm).commit(status)
} }
@ -254,14 +247,8 @@ abstract class AbstractCoroutinesTransactionAspectTests {
} }
} }
val itb = advised(tb, rtm, tas) as TestBean val itb = advised(tb, rtm, tas) as TestBean
runBlocking { assertThatExceptionOfType(CannotCreateTransactionException::class.java)
try { .isThrownBy { runBlocking { itb.getName() } }
itb.getName()
}
catch (actual: Exception) {
assertThat(actual).isInstanceOf(CannotCreateTransactionException::class.java)
}
}
} }
/** /**
@ -270,7 +257,7 @@ abstract class AbstractCoroutinesTransactionAspectTests {
* infrastructure exception was thrown to the client * infrastructure exception was thrown to the client
*/ */
@Test @Test
fun cannotCommitTransaction() { suspend fun cannotCommitTransaction() {
val txatt: TransactionAttribute = DefaultTransactionAttribute() val txatt: TransactionAttribute = DefaultTransactionAttribute()
val m = setNameMethod val m = setNameMethod
val tas = MapTransactionAttributeSource() val tas = MapTransactionAttributeSource()
@ -286,17 +273,15 @@ abstract class AbstractCoroutinesTransactionAspectTests {
val tb = DefaultTestBean() val tb = DefaultTestBean()
val itb = advised(tb, rtm, tas) as TestBean val itb = advised(tb, rtm, tas) as TestBean
val name = "new name" val name = "new name"
runBlocking { try {
try { itb.setName(name)
itb.setName(name) }
} catch (actual: Exception) {
catch (actual: Exception) { assertThat(actual).isInstanceOf(ex.javaClass)
assertThat(actual).isInstanceOf(ex.javaClass) assertThat(actual).hasMessage(ex.message)
assertThat(actual).hasMessage(ex.message)
}
// Should have invoked target and changed name
assertThat(itb.getName()).isEqualTo(name)
} }
// Should have invoked target and changed name
assertThat(itb.getName()).isEqualTo(name)
} }
private fun checkReactiveTransaction(expected: Boolean) { private fun checkReactiveTransaction(expected: Boolean) {

49
spring-tx/src/test/kotlin/org/springframework/transaction/reactive/TransactionalOperatorExtensionsTests.kt

@ -22,6 +22,7 @@ import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.toList import kotlinx.coroutines.flow.toList
import kotlinx.coroutines.runBlocking import kotlinx.coroutines.runBlocking
import org.assertj.core.api.Assertions.assertThat import org.assertj.core.api.Assertions.assertThat
import org.assertj.core.api.Assertions.assertThatIllegalStateException
import org.junit.jupiter.api.Test import org.junit.jupiter.api.Test
import org.springframework.transaction.support.DefaultTransactionDefinition import org.springframework.transaction.support.DefaultTransactionDefinition
import kotlin.coroutines.AbstractCoroutineContextElement import kotlin.coroutines.AbstractCoroutineContextElement
@ -33,13 +34,11 @@ class TransactionalOperatorExtensionsTests {
@Test @Test
@Suppress("UNUSED_VARIABLE") @Suppress("UNUSED_VARIABLE")
fun commitWithSuspendingFunction() { suspend fun commitWithSuspendingFunction() {
val operator = TransactionalOperator.create(tm, DefaultTransactionDefinition()) val operator = TransactionalOperator.create(tm, DefaultTransactionDefinition())
runBlocking { val returnValue: Boolean = operator.executeAndAwait {
val returnValue: Boolean = operator.executeAndAwait { delay(1)
delay(1) true
true
}
} }
assertThat(tm.commit).isTrue() assertThat(tm.commit).isTrue()
assertThat(tm.rollback).isFalse() assertThat(tm.rollback).isFalse()
@ -47,13 +46,11 @@ class TransactionalOperatorExtensionsTests {
@Test @Test
@Suppress("UNUSED_VARIABLE") @Suppress("UNUSED_VARIABLE")
fun commitWithEmptySuspendingFunction() { suspend fun commitWithEmptySuspendingFunction() {
val operator = TransactionalOperator.create(tm, DefaultTransactionDefinition()) val operator = TransactionalOperator.create(tm, DefaultTransactionDefinition())
runBlocking { val returnValue: Boolean? = operator.executeAndAwait {
val returnValue: Boolean? = operator.executeAndAwait { delay(1)
delay(1) null
null
}
} }
assertThat(tm.commit).isTrue() assertThat(tm.commit).isTrue()
assertThat(tm.rollback).isFalse() assertThat(tm.rollback).isFalse()
@ -62,22 +59,20 @@ class TransactionalOperatorExtensionsTests {
@Test @Test
fun rollbackWithSuspendingFunction() { fun rollbackWithSuspendingFunction() {
val operator = TransactionalOperator.create(tm, DefaultTransactionDefinition()) val operator = TransactionalOperator.create(tm, DefaultTransactionDefinition())
runBlocking { assertThatIllegalStateException().isThrownBy {
try { runBlocking {
operator.executeAndAwait { operator.executeAndAwait {
delay(1) delay(1)
throw IllegalStateException() throw IllegalStateException()
} }
} catch (ex: IllegalStateException) {
assertThat(tm.commit).isFalse()
assertThat(tm.rollback).isTrue()
return@runBlocking
} }
} }
assertThat(tm.commit).isFalse()
assertThat(tm.rollback).isTrue()
} }
@Test @Test
fun commitWithFlow() { suspend fun commitWithFlow() {
val operator = TransactionalOperator.create(tm, DefaultTransactionDefinition()) val operator = TransactionalOperator.create(tm, DefaultTransactionDefinition())
val flow = flow { val flow = flow {
emit(1) emit(1)
@ -85,10 +80,8 @@ class TransactionalOperatorExtensionsTests {
emit(3) emit(3)
emit(4) emit(4)
} }
runBlocking { val list = flow.transactional(operator).toList()
val list = flow.transactional(operator).toList() assertThat(list).hasSize(4)
assertThat(list).hasSize(4)
}
assertThat(tm.commit).isTrue() assertThat(tm.commit).isTrue()
assertThat(tm.rollback).isFalse() assertThat(tm.rollback).isFalse()
} }
@ -100,15 +93,13 @@ class TransactionalOperatorExtensionsTests {
delay(1) delay(1)
throw IllegalStateException() throw IllegalStateException()
} }
runBlocking { assertThatIllegalStateException().isThrownBy {
try { runBlocking {
flow.transactional(operator).toList() flow.transactional(operator).toList()
} catch (ex: IllegalStateException) {
assertThat(tm.commit).isFalse()
assertThat(tm.rollback).isTrue()
return@runBlocking
} }
} }
assertThat(tm.commit).isFalse()
assertThat(tm.rollback).isTrue()
} }
@Test @Test

29
spring-web/src/test/kotlin/org/springframework/web/server/ServerWebExchangeExtensionsTest.kt

@ -19,7 +19,6 @@ package org.springframework.web.server
import io.mockk.every import io.mockk.every
import io.mockk.mockk import io.mockk.mockk
import io.mockk.verify import io.mockk.verify
import kotlinx.coroutines.runBlocking
import org.assertj.core.api.Assertions.assertThat import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.Test import org.junit.jupiter.api.Test
import org.springframework.http.codec.multipart.Part import org.springframework.http.codec.multipart.Part
@ -35,44 +34,36 @@ import java.security.Principal
class ServerWebExchangeExtensionsTest { class ServerWebExchangeExtensionsTest {
@Test @Test
fun `awaitFormData extension`() { suspend fun `awaitFormData extension`() {
val exchange = mockk<ServerWebExchange>() val exchange = mockk<ServerWebExchange>()
val multiMap = mockk<MultiValueMap<String, String>>() val multiMap = mockk<MultiValueMap<String, String>>()
every { exchange.formData } returns Mono.just(multiMap) every { exchange.formData } returns Mono.just(multiMap)
runBlocking { assertThat(exchange.awaitFormData()).isEqualTo(multiMap)
assertThat(exchange.awaitFormData()).isEqualTo(multiMap)
}
} }
@Test @Test
fun `awaitMultipartData extension`() { suspend fun `awaitMultipartData extension`() {
val exchange = mockk<ServerWebExchange>() val exchange = mockk<ServerWebExchange>()
val multiMap = mockk<MultiValueMap<String, Part>>() val multiMap = mockk<MultiValueMap<String, Part>>()
every { exchange.multipartData } returns Mono.just(multiMap) every { exchange.multipartData } returns Mono.just(multiMap)
runBlocking { assertThat(exchange.awaitMultipartData()).isEqualTo(multiMap)
assertThat(exchange.awaitMultipartData()).isEqualTo(multiMap)
}
} }
@Test @Test
fun `awaitPrincipal extension`() { suspend fun `awaitPrincipal extension`() {
val exchange = mockk<ServerWebExchange>() val exchange = mockk<ServerWebExchange>()
val principal = mockk<Principal>() val principal = mockk<Principal>()
every { exchange.getPrincipal<Principal>() } returns Mono.just(principal) every { exchange.getPrincipal<Principal>() } returns Mono.just(principal)
runBlocking { assertThat(exchange.awaitPrincipal<Principal>()).isEqualTo(principal)
assertThat(exchange.awaitPrincipal<Principal>()).isEqualTo(principal)
}
verify { exchange.getPrincipal<Principal>() } verify { exchange.getPrincipal<Principal>() }
} }
@Test @Test
fun `awaitSession extension`() { suspend fun `awaitSession extension`() {
val exchange = mockk<ServerWebExchange>() val exchange = mockk<ServerWebExchange>()
val session = mockk<WebSession>() val session = mockk<WebSession>()
every { exchange.session } returns Mono.just(session) every { exchange.session } returns Mono.just(session)
runBlocking { assertThat(exchange.awaitSession()).isEqualTo(session)
assertThat(exchange.awaitSession()).isEqualTo(session)
}
} }
@Test @Test
@ -80,9 +71,7 @@ class ServerWebExchangeExtensionsTest {
val builder = mockk<ServerWebExchange.Builder>() val builder = mockk<ServerWebExchange.Builder>()
val principal = mockk<Principal>() val principal = mockk<Principal>()
every { builder.principal(any<Mono<Principal>>()) } returns builder every { builder.principal(any<Mono<Principal>>()) } returns builder
runBlocking { assertThat(builder.principal { principal }).isEqualTo(builder)
assertThat(builder.principal { principal }).isEqualTo(builder)
}
verify { builder.principal(any<Mono<Principal>>()) } verify { builder.principal(any<Mono<Principal>>()) }
} }

3
spring-web/src/test/kotlin/org/springframework/web/service/invoker/HttpServiceMethodKotlinTests.kt

@ -18,7 +18,6 @@ package org.springframework.web.service.invoker
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.toList import kotlinx.coroutines.flow.toList
import kotlinx.coroutines.runBlocking
import org.assertj.core.api.Assertions.assertThat import org.assertj.core.api.Assertions.assertThat
import org.assertj.core.api.Assertions.assertThatIllegalStateException import org.assertj.core.api.Assertions.assertThatIllegalStateException
import org.junit.jupiter.api.Test import org.junit.jupiter.api.Test
@ -42,7 +41,7 @@ class KotlinHttpServiceMethodTests {
private val reactorProxyFactory = HttpServiceProxyFactory.builderFor(this.reactorExchangeAdapter).build() private val reactorProxyFactory = HttpServiceProxyFactory.builderFor(this.reactorExchangeAdapter).build()
@Test @Test
fun coroutinesService(): Unit = runBlocking { suspend fun coroutinesService() {
val service = reactorProxyFactory.createClient(FunctionsService::class.java) val service = reactorProxyFactory.createClient(FunctionsService::class.java)
val stringBody = service.stringBody() val stringBody = service.stringBody()

61
spring-webflux/src/test/kotlin/org/springframework/web/reactive/function/client/ClientResponseExtensionsTests.kt

@ -19,7 +19,6 @@ package org.springframework.web.reactive.function.client
import io.mockk.every import io.mockk.every
import io.mockk.mockk import io.mockk.mockk
import io.mockk.verify import io.mockk.verify
import kotlinx.coroutines.runBlocking
import org.assertj.core.api.Assertions.assertThat import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.Test import org.junit.jupiter.api.Test
import org.springframework.core.ParameterizedTypeReference import org.springframework.core.ParameterizedTypeReference
@ -74,99 +73,79 @@ class ClientResponseExtensionsTests {
} }
@Test @Test
fun awaitBody() { suspend fun awaitBody() {
val response = mockk<ClientResponse>() val response = mockk<ClientResponse>()
every { response.bodyToMono<String>() } returns Mono.just("foo") every { response.bodyToMono<String>() } returns Mono.just("foo")
runBlocking { assertThat(response.awaitBody<String>()).isEqualTo("foo")
assertThat(response.awaitBody<String>()).isEqualTo("foo")
}
} }
@Test @Test
fun `awaitBody with KClass parameter`() { suspend fun `awaitBody with KClass parameter`() {
val response = mockk<ClientResponse>() val response = mockk<ClientResponse>()
every { response.bodyToMono(String::class.java) } returns Mono.just("foo") every { response.bodyToMono(String::class.java) } returns Mono.just("foo")
runBlocking { assertThat(response.awaitBody(String::class)).isEqualTo("foo")
assertThat(response.awaitBody(String::class)).isEqualTo("foo")
}
} }
@Test @Test
fun awaitBodyOrNull() { suspend fun awaitBodyOrNull() {
val response = mockk<ClientResponse>() val response = mockk<ClientResponse>()
every { response.bodyToMono<String>() } returns Mono.empty() every { response.bodyToMono<String>() } returns Mono.empty()
runBlocking { assertThat(response.awaitBodyOrNull<String>()).isNull()
assertThat(response.awaitBodyOrNull<String>()).isNull()
}
} }
@Test @Test
fun `awaitBodyOrNullGeneric with KClass parameter`() { suspend fun `awaitBodyOrNullGeneric with KClass parameter`() {
val response = mockk<ClientResponse>() val response = mockk<ClientResponse>()
every { response.bodyToMono(String::class.java) } returns Mono.empty() every { response.bodyToMono(String::class.java) } returns Mono.empty()
runBlocking { assertThat(response.awaitBodyOrNull(String::class)).isNull()
assertThat(response.awaitBodyOrNull(String::class)).isNull()
}
} }
@Test @Test
fun awaitEntity() { suspend fun awaitEntity() {
val response = mockk<ClientResponse>() val response = mockk<ClientResponse>()
val entity = ResponseEntity("foo", HttpStatus.OK) val entity = ResponseEntity("foo", HttpStatus.OK)
every { response.toEntity<String>() } returns Mono.just(entity) every { response.toEntity<String>() } returns Mono.just(entity)
runBlocking { assertThat(response.awaitEntity<String>()).isEqualTo(entity)
assertThat(response.awaitEntity<String>()).isEqualTo(entity)
}
} }
@Test @Test
fun `awaitEntity with KClass parameter`() { suspend fun `awaitEntity with KClass parameter`() {
val response = mockk<ClientResponse>() val response = mockk<ClientResponse>()
val entity = ResponseEntity("foo", HttpStatus.OK) val entity = ResponseEntity("foo", HttpStatus.OK)
every { response.toEntity(String::class.java) } returns Mono.just(entity) every { response.toEntity(String::class.java) } returns Mono.just(entity)
runBlocking { assertThat(response.awaitEntity(String::class)).isEqualTo(entity)
assertThat(response.awaitEntity(String::class)).isEqualTo(entity)
}
} }
@Test @Test
fun awaitEntityList() { suspend fun awaitEntityList() {
val response = mockk<ClientResponse>() val response = mockk<ClientResponse>()
val entity = ResponseEntity(listOf("foo"), HttpStatus.OK) val entity = ResponseEntity(listOf("foo"), HttpStatus.OK)
every { response.toEntityList<String>() } returns Mono.just(entity) every { response.toEntityList<String>() } returns Mono.just(entity)
runBlocking { assertThat(response.awaitEntityList<String>()).isEqualTo(entity)
assertThat(response.awaitEntityList<String>()).isEqualTo(entity)
}
} }
@Test @Test
fun `awaitEntityList with KClass parameter`() { suspend fun `awaitEntityList with KClass parameter`() {
val response = mockk<ClientResponse>() val response = mockk<ClientResponse>()
val entity = ResponseEntity(listOf("foo"), HttpStatus.OK) val entity = ResponseEntity(listOf("foo"), HttpStatus.OK)
every { response.toEntityList(String::class.java) } returns Mono.just(entity) every { response.toEntityList(String::class.java) } returns Mono.just(entity)
runBlocking { assertThat(response.awaitEntityList(String::class)).isEqualTo(entity)
assertThat(response.awaitEntityList(String::class)).isEqualTo(entity)
}
} }
@Test @Test
fun awaitBodilessEntity() { suspend fun awaitBodilessEntity() {
val response = mockk<ClientResponse>() val response = mockk<ClientResponse>()
val entity = mockk<ResponseEntity<Void>>() val entity = mockk<ResponseEntity<Void>>()
every { response.toBodilessEntity() } returns Mono.just(entity) every { response.toBodilessEntity() } returns Mono.just(entity)
runBlocking { assertThat(response.awaitBodilessEntity()).isEqualTo(entity)
assertThat(response.awaitBodilessEntity()).isEqualTo(entity)
}
} }
@Test @Test
fun createExceptionAndAwait() { suspend fun createExceptionAndAwait() {
val response = mockk<ClientResponse>() val response = mockk<ClientResponse>()
val exception = mockk<WebClientResponseException>() val exception = mockk<WebClientResponseException>()
every { response.createException() } returns Mono.just(exception) every { response.createException() } returns Mono.just(exception)
runBlocking { assertThat(response.createExceptionAndAwait()).isEqualTo(exception)
assertThat(response.createExceptionAndAwait()).isEqualTo(exception)
}
} }
class Foo class Foo

7
spring-webflux/src/test/kotlin/org/springframework/web/reactive/function/client/CoExchangeFilterFunctionTests.kt

@ -18,7 +18,6 @@ package org.springframework.web.reactive.function.client
import io.mockk.mockk import io.mockk.mockk
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
import kotlinx.coroutines.runBlocking
import org.assertj.core.api.Assertions.assertThat import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.Test import org.junit.jupiter.api.Test
@ -30,12 +29,10 @@ import org.junit.jupiter.api.Test
class CoExchangeFilterFunctionTests { class CoExchangeFilterFunctionTests {
@Test @Test
fun exchange() { suspend fun exchange() {
val response = mockk<ClientResponse>() val response = mockk<ClientResponse>()
val exchangeFunction = MyCoExchangeFunction(response) val exchangeFunction = MyCoExchangeFunction(response)
runBlocking { assertThat(exchangeFunction.exchange(mockk())).isEqualTo(response)
assertThat(exchangeFunction.exchange(mockk())).isEqualTo(response)
}
} }
} }

64
spring-webflux/src/test/kotlin/org/springframework/web/reactive/function/client/WebClientExtensionsTests.kt

@ -102,12 +102,10 @@ class WebClientExtensionsTests {
} }
@Test @Test
fun `awaitExchange with function parameter`() { suspend fun `awaitExchange with function parameter`() {
val foo = mockk<Foo>() val foo = mockk<Foo>()
every { requestBodySpec.exchangeToMono(any<Function<ClientResponse, Mono<Foo>>>()) } returns Mono.just(foo) every { requestBodySpec.exchangeToMono(any<Function<ClientResponse, Mono<Foo>>>()) } returns Mono.just(foo)
runBlocking { assertThat(requestBodySpec.awaitExchange { foo }).isEqualTo(foo)
assertThat(requestBodySpec.awaitExchange { foo }).isEqualTo(foo)
}
} }
@Test @Test
@ -123,21 +121,17 @@ class WebClientExtensionsTests {
} }
@Test @Test
fun `awaitExchangeOrNull returning null`() { suspend fun `awaitExchangeOrNull returning null`() {
val foo = mockk<Foo>() val foo = mockk<Foo>()
every { requestBodySpec.exchangeToMono(any<Function<ClientResponse, Mono<Foo>>>()) } returns Mono.empty() every { requestBodySpec.exchangeToMono(any<Function<ClientResponse, Mono<Foo>>>()) } returns Mono.empty()
runBlocking { assertThat(requestBodySpec.awaitExchangeOrNull { foo }).isEqualTo(null)
assertThat(requestBodySpec.awaitExchangeOrNull { foo }).isEqualTo(null)
}
} }
@Test @Test
fun `awaitExchangeOrNull returning object`() { suspend fun `awaitExchangeOrNull returning object`() {
val foo = mockk<Foo>() val foo = mockk<Foo>()
every { requestBodySpec.exchangeToMono(any<Function<ClientResponse, Mono<Foo>>>()) } returns Mono.just(foo) every { requestBodySpec.exchangeToMono(any<Function<ClientResponse, Mono<Foo>>>()) } returns Mono.just(foo)
runBlocking { assertThat(requestBodySpec.awaitExchangeOrNull { foo }).isEqualTo(foo)
assertThat(requestBodySpec.awaitExchangeOrNull { foo }).isEqualTo(foo)
}
} }
@Test @Test
@ -153,65 +147,53 @@ class WebClientExtensionsTests {
} }
@Test @Test
fun exchangeToFlow() { suspend fun exchangeToFlow() {
val foo = mockk<Foo>() val foo = mockk<Foo>()
every { requestBodySpec.exchangeToFlux(any<Function<ClientResponse, Flux<Foo>>>()) } returns Flux.just(foo, foo) every { requestBodySpec.exchangeToFlux(any<Function<ClientResponse, Flux<Foo>>>()) } returns Flux.just(foo, foo)
runBlocking { assertThat(requestBodySpec.exchangeToFlow {
assertThat(requestBodySpec.exchangeToFlow { flow {
flow { emit(foo)
emit(foo) emit(foo)
emit(foo) }
} }.toList()).isEqualTo(listOf(foo, foo))
}.toList()).isEqualTo(listOf(foo, foo))
}
} }
@Test @Test
fun awaitBody() { suspend fun awaitBody() {
val spec = mockk<WebClient.ResponseSpec>() val spec = mockk<WebClient.ResponseSpec>()
every { spec.bodyToMono<String>() } returns Mono.just("foo") every { spec.bodyToMono<String>() } returns Mono.just("foo")
runBlocking { assertThat(spec.awaitBody<String>()).isEqualTo("foo")
assertThat(spec.awaitBody<String>()).isEqualTo("foo")
}
} }
@Test @Test
fun `awaitBody of type Unit`() { suspend fun `awaitBody of type Unit`() {
val spec = mockk<WebClient.ResponseSpec>() val spec = mockk<WebClient.ResponseSpec>()
val entity = mockk<ResponseEntity<Void>>() val entity = mockk<ResponseEntity<Void>>()
every { spec.toBodilessEntity() } returns Mono.just(entity) every { spec.toBodilessEntity() } returns Mono.just(entity)
runBlocking { assertThat(spec.awaitBody<Unit>()).isEqualTo(Unit)
assertThat(spec.awaitBody<Unit>()).isEqualTo(Unit)
}
} }
@Test @Test
fun awaitBodyOrNull() { suspend fun awaitBodyOrNull() {
val spec = mockk<WebClient.ResponseSpec>() val spec = mockk<WebClient.ResponseSpec>()
every { spec.bodyToMono<String>() } returns Mono.just("foo") every { spec.bodyToMono<String>() } returns Mono.just("foo")
runBlocking { assertThat(spec.awaitBodyOrNull<String>()).isEqualTo("foo")
assertThat(spec.awaitBodyOrNull<String>()).isEqualTo("foo")
}
} }
@Test @Test
fun `awaitBodyOrNull of type Unit`() { suspend fun `awaitBodyOrNull of type Unit`() {
val spec = mockk<WebClient.ResponseSpec>() val spec = mockk<WebClient.ResponseSpec>()
val entity = mockk<ResponseEntity<Void>>() val entity = mockk<ResponseEntity<Void>>()
every { spec.toBodilessEntity() } returns Mono.just(entity) every { spec.toBodilessEntity() } returns Mono.just(entity)
runBlocking { assertThat(spec.awaitBodyOrNull<Unit>()).isEqualTo(Unit)
assertThat(spec.awaitBodyOrNull<Unit>()).isEqualTo(Unit)
}
} }
@Test @Test
fun awaitBodilessEntity() { suspend fun awaitBodilessEntity() {
val spec = mockk<WebClient.ResponseSpec>() val spec = mockk<WebClient.ResponseSpec>()
val entity = mockk<ResponseEntity<Void>>() val entity = mockk<ResponseEntity<Void>>()
every { spec.toBodilessEntity() } returns Mono.just(entity) every { spec.toBodilessEntity() } returns Mono.just(entity)
runBlocking { assertThat(spec.awaitBodilessEntity()).isEqualTo(entity)
assertThat(spec.awaitBodilessEntity()).isEqualTo(entity)
}
} }
@Test @Test

19
spring-webflux/src/test/kotlin/org/springframework/web/reactive/function/client/support/WebClientHttpServiceProxyKotlinTests.kt

@ -15,7 +15,6 @@
*/ */
package org.springframework.web.reactive.function.client.support package org.springframework.web.reactive.function.client.support
import kotlinx.coroutines.runBlocking
import mockwebserver3.MockResponse import mockwebserver3.MockResponse
import mockwebserver3.MockWebServer import mockwebserver3.MockWebServer
import org.assertj.core.api.Assertions.assertThat import org.assertj.core.api.Assertions.assertThat
@ -69,12 +68,10 @@ class KotlinWebClientHttpServiceGroupAdapterServiceProxyTests {
} }
@Test @Test
fun greetingSuspending() { suspend fun greetingSuspending() {
prepareResponse { it.setHeader("Content-Type", "text/plain").body("Hello Spring!") } prepareResponse { it.setHeader("Content-Type", "text/plain").body("Hello Spring!") }
runBlocking { val greeting = initHttpService().getGreetingSuspending()
val greeting = initHttpService().getGreetingSuspending() assertThat(greeting).isEqualTo("Hello Spring!")
assertThat(greeting).isEqualTo("Hello Spring!")
}
} }
@Test @Test
@ -94,7 +91,7 @@ class KotlinWebClientHttpServiceGroupAdapterServiceProxyTests {
} }
@Test @Test
fun greetingSuspendingWithRequestAttribute() { suspend fun greetingSuspendingWithRequestAttribute() {
val attributes: MutableMap<String, Any> = HashMap() val attributes: MutableMap<String, Any> = HashMap()
val webClient = WebClient.builder() val webClient = WebClient.builder()
.baseUrl(server.url("/").toString()) .baseUrl(server.url("/").toString())
@ -105,11 +102,9 @@ class KotlinWebClientHttpServiceGroupAdapterServiceProxyTests {
.build() .build()
prepareResponse { it.setHeader("Content-Type", "text/plain").body("Hello Spring!") } prepareResponse { it.setHeader("Content-Type", "text/plain").body("Hello Spring!") }
val service = initHttpService(webClient) val service = initHttpService(webClient)
runBlocking { val greeting = service.getGreetingSuspendingWithAttribute("myAttributeValue")
val greeting = service.getGreetingSuspendingWithAttribute("myAttributeValue") assertThat(greeting).isEqualTo("Hello Spring!")
assertThat(greeting).isEqualTo("Hello Spring!") assertThat(attributes).containsEntry("myAttribute", "myAttributeValue")
assertThat(attributes).containsEntry("myAttribute", "myAttributeValue")
}
} }
@Test @Test

7
spring-webflux/src/test/kotlin/org/springframework/web/reactive/function/server/RenderingResponseExtensionsTests.kt

@ -19,20 +19,17 @@ package org.springframework.web.reactive.function.server
import io.mockk.every import io.mockk.every
import io.mockk.mockk import io.mockk.mockk
import io.mockk.verify import io.mockk.verify
import kotlinx.coroutines.runBlocking
import org.junit.jupiter.api.Test import org.junit.jupiter.api.Test
import reactor.core.publisher.Mono import reactor.core.publisher.Mono
class RenderingResponseExtensionsTests { class RenderingResponseExtensionsTests {
@Test @Test
fun buildAndAwait() { suspend fun buildAndAwait() {
val builder = mockk<RenderingResponse.Builder>() val builder = mockk<RenderingResponse.Builder>()
val response = mockk<RenderingResponse>() val response = mockk<RenderingResponse>()
every { builder.build() } returns Mono.just(response) every { builder.build() } returns Mono.just(response)
runBlocking { builder.buildAndAwait()
builder.buildAndAwait()
}
verify { verify {
builder.build() builder.build()
} }

49
spring-webflux/src/test/kotlin/org/springframework/web/reactive/function/server/ServerRequestExtensionsTests.kt

@ -19,7 +19,6 @@ package org.springframework.web.reactive.function.server
import io.mockk.every import io.mockk.every
import io.mockk.mockk import io.mockk.mockk
import io.mockk.verify import io.mockk.verify
import kotlinx.coroutines.runBlocking
import org.assertj.core.api.Assertions.assertThat import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.Test import org.junit.jupiter.api.Test
import org.springframework.core.ParameterizedTypeReference import org.springframework.core.ParameterizedTypeReference
@ -70,71 +69,55 @@ class ServerRequestExtensionsTests {
} }
@Test @Test
fun `awaitBody with reified type parameters`() { suspend fun `awaitBody with reified type parameters`() {
every { request.bodyToMono<String>() } returns Mono.just("foo") every { request.bodyToMono<String>() } returns Mono.just("foo")
runBlocking { assertThat(request.awaitBody<String>()).isEqualTo("foo")
assertThat(request.awaitBody<String>()).isEqualTo("foo")
}
} }
@Test @Test
fun `awaitBody with KClass parameters`() { suspend fun `awaitBody with KClass parameters`() {
every { request.bodyToMono(String::class.java) } returns Mono.just("foo") every { request.bodyToMono(String::class.java) } returns Mono.just("foo")
runBlocking { assertThat(request.awaitBody(String::class)).isEqualTo("foo")
assertThat(request.awaitBody(String::class)).isEqualTo("foo")
}
} }
@Test @Test
fun `awaitBodyOrNull with reified type parameters`() { suspend fun `awaitBodyOrNull with reified type parameters`() {
every { request.bodyToMono<String>() } returns Mono.empty() every { request.bodyToMono<String>() } returns Mono.empty()
runBlocking { assertThat(request.awaitBodyOrNull<String>()).isNull()
assertThat(request.awaitBodyOrNull<String>()).isNull()
}
} }
@Test @Test
fun `awaitBodyOrNull with KClass parameters`() { suspend fun `awaitBodyOrNull with KClass parameters`() {
every { request.bodyToMono(String::class.java) } returns Mono.empty() every { request.bodyToMono(String::class.java) } returns Mono.empty()
runBlocking { assertThat(request.awaitBodyOrNull(String::class)).isNull()
assertThat(request.awaitBodyOrNull(String::class)).isNull()
}
} }
@Test @Test
fun awaitFormData() { suspend fun awaitFormData() {
val map = mockk<MultiValueMap<String, String>>() val map = mockk<MultiValueMap<String, String>>()
every { request.formData() } returns Mono.just(map) every { request.formData() } returns Mono.just(map)
runBlocking { assertThat(request.awaitFormData()).isEqualTo(map)
assertThat(request.awaitFormData()).isEqualTo(map)
}
} }
@Test @Test
fun awaitMultipartData() { suspend fun awaitMultipartData() {
val map = mockk<MultiValueMap<String, Part>>() val map = mockk<MultiValueMap<String, Part>>()
every { request.multipartData() } returns Mono.just(map) every { request.multipartData() } returns Mono.just(map)
runBlocking { assertThat(request.awaitMultipartData()).isEqualTo(map)
assertThat(request.awaitMultipartData()).isEqualTo(map)
}
} }
@Test @Test
fun awaitPrincipal() { suspend fun awaitPrincipal() {
val principal = mockk<Principal>() val principal = mockk<Principal>()
every { request.principal() } returns Mono.just(principal) every { request.principal() } returns Mono.just(principal)
runBlocking { assertThat(request.awaitPrincipal()).isEqualTo(principal)
assertThat(request.awaitPrincipal()).isEqualTo(principal)
}
} }
@Test @Test
fun awaitSession() { suspend fun awaitSession() {
val session = mockk<WebSession>() val session = mockk<WebSession>()
every { request.session() } returns Mono.just(session) every { request.session() } returns Mono.just(session)
runBlocking { assertThat(request.awaitSession()).isEqualTo(session)
assertThat(request.awaitSession()).isEqualTo(session)
}
} }
@Test @Test

37
spring-webflux/src/test/kotlin/org/springframework/web/reactive/function/server/ServerResponseExtensionsTests.kt

@ -21,7 +21,6 @@ import io.mockk.mockk
import io.mockk.verify import io.mockk.verify
import io.reactivex.rxjava3.core.Flowable import io.reactivex.rxjava3.core.Flowable
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.runBlocking
import org.assertj.core.api.Assertions.assertThat import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.Test import org.junit.jupiter.api.Test
import org.reactivestreams.Publisher import org.reactivestreams.Publisher
@ -63,39 +62,33 @@ class ServerResponseExtensionsTests {
} }
@Test @Test
fun `BodyBuilder#bodyAndAwait with object parameter`() { suspend fun `BodyBuilder#bodyAndAwait with object parameter`() {
val response = mockk<ServerResponse>() val response = mockk<ServerResponse>()
val body = "foo" val body = "foo"
every { bodyBuilder.bodyValue(ofType<String>()) } returns Mono.just(response) every { bodyBuilder.bodyValue(ofType<String>()) } returns Mono.just(response)
runBlocking { bodyBuilder.bodyValueAndAwait(body)
bodyBuilder.bodyValueAndAwait(body)
}
verify { verify {
bodyBuilder.bodyValue(ofType<String>()) bodyBuilder.bodyValue(ofType<String>())
} }
} }
@Test @Test
fun `BodyBuilder#bodyValueWithTypeAndAwait with object parameter and reified type parameters`() { suspend fun `BodyBuilder#bodyValueWithTypeAndAwait with object parameter and reified type parameters`() {
val response = mockk<ServerResponse>() val response = mockk<ServerResponse>()
val body = listOf("foo", "bar") val body = listOf("foo", "bar")
every { bodyBuilder.bodyValue(ofType<List<String>>(), object : ParameterizedTypeReference<List<String>>() {}) } returns Mono.just(response) every { bodyBuilder.bodyValue(ofType<List<String>>(), object : ParameterizedTypeReference<List<String>>() {}) } returns Mono.just(response)
runBlocking { bodyBuilder.bodyValueWithTypeAndAwait<List<String>>(body)
bodyBuilder.bodyValueWithTypeAndAwait<List<String>>(body)
}
verify { verify {
bodyBuilder.bodyValue(body, object : ParameterizedTypeReference<List<String>>() {}) bodyBuilder.bodyValue(body, object : ParameterizedTypeReference<List<String>>() {})
} }
} }
@Test @Test
fun `BodyBuilder#bodyAndAwait with flow parameter`() { suspend fun `BodyBuilder#bodyAndAwait with flow parameter`() {
val response = mockk<ServerResponse>() val response = mockk<ServerResponse>()
val body = mockk<Flow<List<Foo>>>() val body = mockk<Flow<List<Foo>>>()
every { bodyBuilder.body(ofType<Flow<List<Foo>>>(), object : ParameterizedTypeReference<List<Foo>>() {}) } returns Mono.just(response) every { bodyBuilder.body(ofType<Flow<List<Foo>>>(), object : ParameterizedTypeReference<List<Foo>>() {}) } returns Mono.just(response)
runBlocking { bodyBuilder.bodyAndAwait(body)
bodyBuilder.bodyAndAwait(body)
}
verify { verify {
bodyBuilder.body(ofType<Flow<List<Foo>>>(), object : ParameterizedTypeReference<List<Foo>>() {}) bodyBuilder.body(ofType<Flow<List<Foo>>>(), object : ParameterizedTypeReference<List<Foo>>() {})
} }
@ -126,38 +119,32 @@ class ServerResponseExtensionsTests {
} }
@Test @Test
fun `BodyBuilder#renderAndAwait with a vararg parameter`() { suspend fun `BodyBuilder#renderAndAwait with a vararg parameter`() {
val response = mockk<ServerResponse>() val response = mockk<ServerResponse>()
every { bodyBuilder.render("foo", any(), any()) } returns Mono.just(response) every { bodyBuilder.render("foo", any(), any()) } returns Mono.just(response)
runBlocking { bodyBuilder.renderAndAwait("foo", "bar", "baz")
bodyBuilder.renderAndAwait("foo", "bar", "baz")
}
verify { verify {
bodyBuilder.render("foo", any(), any()) bodyBuilder.render("foo", any(), any())
} }
} }
@Test @Test
fun `BodyBuilder#renderAndAwait with a Map parameter`() { suspend fun `BodyBuilder#renderAndAwait with a Map parameter`() {
val response = mockk<ServerResponse>() val response = mockk<ServerResponse>()
val map = mockk<Map<String, *>>() val map = mockk<Map<String, *>>()
every { bodyBuilder.render("foo", map) } returns Mono.just(response) every { bodyBuilder.render("foo", map) } returns Mono.just(response)
runBlocking { bodyBuilder.renderAndAwait("foo", map)
bodyBuilder.renderAndAwait("foo", map)
}
verify { verify {
bodyBuilder.render("foo", map) bodyBuilder.render("foo", map)
} }
} }
@Test @Test
fun `HeadersBuilder#buildAndAwait`() { suspend fun `HeadersBuilder#buildAndAwait`() {
val response = mockk<ServerResponse>() val response = mockk<ServerResponse>()
val builder = mockk<ServerResponse.HeadersBuilder<*>>() val builder = mockk<ServerResponse.HeadersBuilder<*>>()
every { builder.build() } returns Mono.just(response) every { builder.build() } returns Mono.just(response)
runBlocking { assertThat(builder.buildAndAwait()).isEqualTo(response)
assertThat(builder.buildAndAwait()).isEqualTo(response)
}
} }
class Foo class Foo

Loading…
Cancel
Save