Support test methods with Kotlin suspend modifier #1914
Open
Description
opened on Jun 4, 2019
Goals
Support running suspend test in JUnit Jupiter:
class Kit {
@Test
suspend fun foo() {
delay(1000) // suspend call
assertEquals(1, 1)
}
}
Currently, such test can be written this way:
class Kit {
@Test
fun foo() = runBlocking {
delay(1000) // suspend call
assertEquals(1, 1)
assertThrows { /* ... */ }
Unit // test should return void, but `assertThrows` returns `Throwable`, so `foo` returns `Throwable` too
}
}
Also, will be nice to provide CoroutineScope
through params, or as receiver in extension:
class Kit {
suspend fun foo(scope: CoroutinesScope) { /* ... */ } // (1)
suspend fun CoroutinesScope.foo() { /* ... */ } // (2)
}
1 and 2 actually the same on bytecode level. suspend
is optional.
And finally, support for runBlockingTest
:
class Kit {
suspend fun foo(scope: TestCoroutinesScope) { /* ... */ }
suspend fun TestCoroutinesScope.foo() { /* ... */ }
}
What can be done currently
ParameterResolver
can be used to provide stubs for Continuation
, CoroutineScope
and TestCoroutineScope
. These stub arguments can be replaced with real arguments in invocation.
Problems
Current extensions points not enough to implement this feature as extensions, since:
- Discovery. Jupiter discovers tests that returns
void
, butsuspend fun
returnsObject
; - Invocation.
InvocationInterceptor
in 5.5-M1(SNAPSHOT) don't providing mechanism to override actual invocation, only to decoration of existing invocation. Conversion ofmethod
tokotlinFunction
, and then executing usingcallSuspend
is necessary to executesuspend fun
.
Also, my slides about this topic.
Metadata
Assignees
Type
Projects
Status
Todo
Activity