|
1 | 1 | package br.com.colman.kotest.android.extensions.robolectric |
2 | 2 |
|
3 | 3 | import android.app.Application |
4 | | -import io.kotest.common.runBlocking |
5 | 4 | import io.kotest.core.extensions.ConstructorExtension |
6 | 5 | import io.kotest.core.extensions.TestCaseExtension |
7 | 6 | import io.kotest.core.spec.AutoScan |
8 | 7 | import io.kotest.core.spec.Spec |
9 | 8 | import io.kotest.core.test.TestCase |
10 | 9 | import io.kotest.core.test.TestResult |
| 10 | +import io.kotest.core.test.isRootTest |
| 11 | +import kotlinx.coroutines.asCoroutineDispatcher |
| 12 | +import kotlinx.coroutines.withContext |
11 | 13 | import org.robolectric.annotation.Config |
12 | | -import java.util.concurrent.Callable |
| 14 | +import org.robolectric.internal.bytecode.Sandbox |
13 | 15 | import kotlin.reflect.KClass |
14 | 16 | import kotlin.reflect.full.findAnnotation |
15 | 17 | import kotlin.time.Duration |
16 | 18 | import java.util.WeakHashMap |
| 19 | +import java.util.concurrent.ExecutorService |
17 | 20 |
|
18 | 21 | /** |
19 | 22 | * We override TestCaseExtension to configure the Robolectric environment because TestCase intercept |
@@ -110,19 +113,30 @@ class RobolectricExtension : ConstructorExtension, TestCaseExtension { |
110 | 113 | execute: suspend (TestCase) -> TestResult, |
111 | 114 | ): TestResult { |
112 | 115 | val containedRobolectricRunner = runnerMap[testCase.spec]!! |
113 | | - // sdkEnvironment.runOnMainThread is important to ensure Robolectric's |
| 116 | + // Using sdkEnvironment.executorService to ensure Robolectric's |
114 | 117 | // looper state doesn't carry over to the next test class. |
115 | | - return containedRobolectricRunner.sdkEnvironment.runOnMainThread( |
116 | | - Callable { |
| 118 | + val executorService = containedRobolectricRunner.sdkEnvironment.getExecutorService() |
| 119 | + return withContext(executorService.asCoroutineDispatcher()) { |
| 120 | + if (testCase.isRootTest()) { |
117 | 121 | containedRobolectricRunner.containedBefore() |
118 | | - val result = runBlocking { execute(testCase) } |
| 122 | + } |
| 123 | + val result = execute(testCase) |
| 124 | + if (testCase.isRootTest()) { |
119 | 125 | containedRobolectricRunner.containedAfter() |
120 | | - result |
121 | | - }, |
122 | | - ) |
| 126 | + } |
| 127 | + result |
| 128 | + } |
123 | 129 | } |
124 | 130 | } |
125 | 131 |
|
| 132 | +private fun Sandbox.getExecutorService(): ExecutorService { |
| 133 | + val field = Sandbox::class.java.declaredFields |
| 134 | + .firstOrNull { it.type == ExecutorService::class.java } |
| 135 | + checkNotNull(field) { "Not found ExecutorService field." } |
| 136 | + field.isAccessible = true |
| 137 | + return field.get(this) as ExecutorService |
| 138 | +} |
| 139 | + |
126 | 140 | internal class KotestDefaultApplication : Application() |
127 | 141 |
|
128 | 142 | annotation class RobolectricTest( |
|
0 commit comments