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¶
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)
Advances the current time by delay.
Stability warning¶
The KotlinX.Coroutines team is considering removing this functionality. Learn more in #3919.
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)
Delays until the virtual time reaches instant, executing all enqueued tasks in order.
delayUntil is useful to artificially trigger time-dependent algorithms. To set the initial time at the start of the test, use set.
@ExperimentalCoroutinesApi
suspend fun Time.delayUntil(isoString: String)
Delays until the virtual time reaches isoString, formatted as an ISO 8601 timestamp, executing all enqueued tasks in order.
delayUntil is useful to artificially trigger time-dependent algorithms. To set the initial time at the start of the test, use set.
See also
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