https://kotlinlang.org logo
#coroutines
Title
# coroutines
a

Adecker

02/03/2023, 8:03 PM
Is there a way to access the current clock time in production (
System.currentTimeMillis()
or similar…) that is compatible with the virtual clock time in
kotlinx-coroutines-test
? I found a reference to an older method that I don’t think will work since
DelayController
is deprecated, but I’m not able to find any methods to replace it.
h

hfhbd

02/03/2023, 8:08 PM
Depending on your use-case you could use a TimeSource or a kotlinx-datetime Clock
a

Adecker

02/03/2023, 8:13 PM
I suppose I’m wondering more if there’s a way to get that info from the coroutineContext without referencing
TestCoroutineScheduler
in production code. I’m currently passing in a parameter to provide the time, but it’s not the most convenient to pass it through multiple functions.
h

hfhbd

02/03/2023, 8:15 PM
If you only want to inject it, you could either use a "real" di framework or use coroutineContext and inject it manually with your own class and key.
a

Adecker

02/03/2023, 8:21 PM
The goal is to write a time oriented flow function that leverages the virtual clock during tests automatically. Injection is the bad/not-great solution, I was hoping for a solution that works in any coroutineContext without extra setup.
h

hfhbd

02/03/2023, 8:26 PM
Could you provide your flow? You could also use
delay
in your flow BTW I mean this:
Copy code
@ExperimentalTime
class TimeSourceContext(timeSource: TimeSource): CoroutineContext.Element, TimeSource by timeSource {
  override val key: CoroutineContext.Key<TimeSourceContext> = TimeSourceContext
  companion object: CoroutineContext.Key<TimeSourceContext>
}
    
@Test
fun a() = runTest {
  withContext(TimeSourceContext(testTimeSource)) {
    val timeSource: TimeSource = coroutineContext[TimeSourceContext]!!
  }
}
a

Adecker

02/03/2023, 8:30 PM
that would be great if it were a standard context element, but I don’t want to add hidden dependencies on the context the flow is collected in.
h

hfhbd

02/03/2023, 8:48 PM
Hm, I see, yeah making the context itself a TimeSource would be nice too, to run
measureTime
or getting a
TimeMark
without di.
c

CLOVIS

02/03/2023, 9:40 PM
A simple KotlinX.Datetime Clock implementation that uses the TestApplication context: https://gitlab.com/opensavvy/formulaide/-/blob/main/test/src/commonMain/kotlin/utils/TestClock.kt#L10 Your code:
Copy code
fun foo(clock: Clock) {
    println(clock.now())
}
Production usage (or use your favorite DI lib):
Copy code
foo(Clock.System)
Test usage:
Copy code
@Test
fun testFoo() = runTest {
    foo(testClock())
}
h

hfhbd

02/03/2023, 10:07 PM
But you still need to pass the clock
53 Views