I'm porting some coroutines-based tests from 1.5.0...
# coroutines
s
I'm porting some coroutines-based tests from 1.5.0 to 1.6.4 and one of those tests requires a custom Dispatcher. However, I can't find a way to implement the same behaviour with the new test APIs, as I can't extend
TestDispatcher
, and I can't wrap it. How would one do it?
I'd add, I also can't create a TestCoroutineScheduler as it's a closed class and there is no interface to implement, either
j
How did you write those tests initially? If you're using a custom dispatcher, why do you want to extend the test dispatcher or test coroutines scheduler? Why can't you just use your existing code for this test?
s
I didn't, that's another issue. I'm fixing up somebody else's tests 😄
And I can't just use the existing code cause the API they use have been removed in the meantime (I would obviously not have had to chang the tests if everything were fine)
d
Hi! I'd do something like this:
Copy code
From f6fbc81476e8b900b8e38795e5d78cf3321623b6 Mon Sep 17 00:00:00 2001
From: Dmitry Khalanskiy <Dmitry.Khalanskiy@jetbrains.com>
Date: Thu, 29 Dec 2022 13:40:01 +0100
Subject: [PATCH] Modify NonpreciseTestCoroutineDispatcher not implement a
 DelayController

---
 .../kotlin/org/jetbrains/skiko/FrameLimiterTest.kt | 14 +++++---------
 1 file changed, 5 insertions(+), 9 deletions(-)

diff --git a/skiko/src/jvmTest/kotlin/org/jetbrains/skiko/FrameLimiterTest.kt b/skiko/src/jvmTest/kotlin/org/jetbrains/skiko/FrameLimiterTest.kt
index c95ae4cd..faaed8b3 100644
--- a/skiko/src/jvmTest/kotlin/org/jetbrains/skiko/FrameLimiterTest.kt
+++ b/skiko/src/jvmTest/kotlin/org/jetbrains/skiko/FrameLimiterTest.kt
@@ -247,21 +247,17 @@ class FrameLimiterTest {
     private fun runFrameTest(
         delayPrecisionMillis: Long,
         block: suspend TestCoroutineScope.() -> Unit
-    ) = runBlockingTest{
-        val dispatcher = NonpreciseTestCoroutineDispatcher(delayPrecisionMillis)
-        dispatcher.pauseDispatcher()
-        val scope = TestCoroutineScope(dispatcher)
-        scope.launch {
-            scope.block()
+    ) = runBlockingTest {
+        withContext(NonpreciseTestCoroutineDispatcher(delayPrecisionMillis)) {
+            block()
         }
-        dispatcher.advanceUntilIdle()
     }
 
     @OptIn(InternalCoroutinesApi::class)
     private class NonpreciseTestCoroutineDispatcher(
         private val delayPrecisionMillis: Long,
         private val original: TestCoroutineDispatcher = TestCoroutineDispatcher()
-    ) : CoroutineDispatcher(), Delay, DelayController by original {
+    ) : CoroutineDispatcher(), Delay {
         override fun dispatch(context: CoroutineContext, block: Runnable) {
             original.dispatch(context, block)
         }
@@ -271,4 +267,4 @@ class FrameLimiterTest {
             original.scheduleResumeAfterDelay(delay, continuation)
         }
     }
-}
\ No newline at end of file
+}
-- 
2.34.1
This approach should work just as well and doesn't require the wrapper to also be a test dispatcher.
Just in case: this is a
.patch
file.
s
Thanks 🙏
@Dmitry Khalanskiy [JB] if I were to use the newer, non-deprecated (but experimental)
runTest
API instead of the deprecated
runBlockingTest
, this wouldn't work though. Is that something that is even possible, out of curiosity?
Cause this test file is all full of deprecated stuff, and I have fixed other tests to use the newer
runTest
API... it's annoying me a bit that I have to use the deprecated API 🙂
d
Sure, after the proposed change, replace all the deprecated stuff with the corresponding non-deprecated things (
TestCoroutineDispatcher
->
TestDispatcher
etc), and everything should still work. Just make sure to pass the
testScheduler
to a newly-constructed
StandardTestDispatcher
. Sorry for being brief, I'm on a vacation and typing from my phone.
s
Thanks, I'll try 🙂