Time¶
Constructors¶
Time¶
@ExperimentalCoroutinesApi
constructor(environment: TestEnvironment)
Properties¶
clock¶
Creates a Clock that follows the virtual time in this test.
Example
See also
-
Time.source: Measure elapsed time.
now¶
Access the current virtual time within this test, as an Instant.
Example
test("Using the virtual time") {
val initial = time.now
// …do something…
delay(5000)
check(time.now == initial + 5000)
}
For the specific use-case of measuring elapsed time, see Time.source.
See also
clock: To pass the time to another system.
nowMillis¶
Accesses the current time inside the test, in milliseconds.
Example
test("Using the virtual time") {
val initial = time.nowMillis
// …do something…
delay(5000)
check(time.nowMillis == initial + 5000)
}
For the specific use-case of measuring elapsed time, see Time.source.
See also
scheduler¶
Accessor for the underlying TestCoroutineScheduler, which controls the current time.
Delay-skipping behavior is implemented by this dispatcher. Only delay calls within this dispatcher can be skipped and can advance the virtual time. That is, using code like withContext(Dispatchers.IO) { … } overrides the dispatcher and disables delay-skipping for the entire block.
Sometimes, you may need to instantiate a service within your tests, that you want to internally use delay-skipping. In these situations, you may need to pass the scheduler:
test("Test a cron service") {
val cron = CronService(coroutineContext = time.scheduler)
var witness = false
cron.runIn(2.minutes) { witness = true }
check(witness == false)
delay(2.minutes)
check(witness == true)
}
If the service expects a CoroutineScope, see foregroundScope and backgroundScope instead.
source¶
Access a time source which can be used to measure elapsed time, as controlled with time.
Example
Functions¶
advanceBy¶
@ExperimentalCoroutinesApi
fun Time.advanceBy(delay: Duration)
Advances the current time by delay.
Example
test("Hello world") {
val start = time.source.markNow()
time.advanceBy(2.minutes)
val elapsed = start.elapsedNow()
assertEquals(2.minutes, elapsed)
}
Stability warning
The KotlinX.Coroutines team is considering removing this functionality. Learn more in #3919.
advanceByMillis¶
@ExperimentalCoroutinesApi
fun Time.advanceByMillis(delay: Long)
advanceUntilIdle¶
Runs all enqueued tasks in the specified order, advancing the virtual time as needed until there are no more scheduled tasks.
This is similar to delay(Long.MAX_VALUE), except it leaves the virtual time on whenever the last task was scheduled.
Example
test("Execute subtasks") {
launch {
delay(1000)
println("A")
launch {
delay(3000)
println("B")
}
}
launch {
delay(2000)
println("C")
}
time.advanceUntilIdle()
assertEquals(4000, time.nowMillis)
}
Background tasks
This method advances time until all the last foreground tasks's scheduled time. There may be background tasks that are scheduled for later.
Stability warning
The KotlinX.Coroutines team is considering removing this functionality. Learn more in #3919.
delayUntil¶
@ExperimentalCoroutinesApi
suspend fun Time.delayUntil(instant: Instant)
@ExperimentalCoroutinesApi
suspend fun Time.delayUntil(isoString: String)
runCurrent¶
Runs all enqueued tasks at this moment in the virtual time.
Example
test("Execute task") {
launchInBackground {
delay(1000)
println("Hello world!")
}
launchInBackground {
delay(2000)
println("Will never be printed")
}
time.advanceByMillis(1000)
time.runCurrent() // prints "Hello world!"
}
Stability warning
The KotlinX.Coroutines team is considering removing this functionality. Learn more in #3919.
set¶
@ExperimentalCoroutinesApi
suspend fun Time.set(instant: Instant)
Advances the virtual time until it reaches instant.
Comparison with delayUntil
This function is identical in behavior to delayUntil. It exists because tests often read better when using it to set the initial date:
test("Some test") {
// Given:
time.set(Instant.parse("2024-02-13T21:32:41Z"))
// When:
// …
delayUntil(Instant.parse("2024-02-13T21:35:01Z"))
// …
// Then:
// …
}
We recommend using set to set the initial date at the very start of a test, and using delayUntil inside the test logic.
It is not possible to set the time to a date in the past.
@ExperimentalCoroutinesApi
suspend fun Time.set(isoString: String)
Advances the virtual time until it reaches isoString, formatted as an ISO 8601 timestamp.
It is not possible to set the time to a date in the past.
Example
test("Everything should behave the same on December 31st") {
time.set("2022-12-31T23:37:00Z")
// …
}
Comparison with delayUntil
This function is identical in behavior to delayUntil. It exists because tests often read better when using it to set the initial date:
test("Some test") {
// Given:
time.set("2024-02-13T21:32:41Z")
// When:
// …
delayUntil("2024-02-13T21:35:01Z")
// …
// Then:
// …
}
We recommend using set to set the initial date at the very start of a test, and using delayUntil inside the test logic.
See also
-
now: Access the current time -
delay: Wait for some duration -
delayUntil: Wait for a specific time