1
+ package com.baeldung.schedulertimer
2
+
3
+ import kotlinx.coroutines.CoroutineScope
4
+ import kotlinx.coroutines.Job
5
+ import kotlinx.coroutines.TimeoutCancellationException
6
+ import kotlinx.coroutines.delay
7
+ import kotlinx.coroutines.isActive
8
+ import kotlinx.coroutines.launch
9
+ import kotlinx.coroutines.runBlocking
10
+ import kotlinx.coroutines.withTimeout
11
+ import org.assertj.core.api.Assertions.assertThat
12
+ import org.assertj.core.api.Assertions.within
13
+ import org.junit.jupiter.api.Assertions.assertTrue
14
+ import org.junit.jupiter.api.Test
15
+ import org.junit.jupiter.api.assertThrows
16
+
17
+ fun CoroutineScope.startTimer (delay : Long = 1000L, task : suspend () -> Unit ): Job {
18
+ return launch {
19
+ delay(delay)
20
+ task()
21
+ }
22
+ }
23
+
24
+ fun CoroutineScope.startInfiniteScheduler (interval : Long = 1000L, task : suspend () -> Unit ): Job {
25
+ return launch {
26
+ while (isActive) {
27
+ task()
28
+ delay(interval)
29
+ }
30
+ }
31
+ }
32
+
33
+ suspend fun runWithTimeout (timeout : Long , task : suspend () -> Unit ) {
34
+ withTimeout(timeout) {
35
+ task()
36
+ }
37
+ }
38
+
39
+
40
+ class SchedulerTimerUnitTest {
41
+
42
+ @Test
43
+ fun `timer executes task after delay` () = runBlocking {
44
+ var taskExecuted = false
45
+ val task: suspend () -> Unit = { taskExecuted = true }
46
+
47
+ startTimer(delay = 1000L , task = task)
48
+ delay(1500L )
49
+
50
+ assertTrue(taskExecuted)
51
+ }
52
+
53
+ @Test
54
+ fun `infinite scheduler stops when scope is canceled` (): Unit = runBlocking {
55
+ var taskExecutionCount = 0
56
+ val task: suspend () -> Unit = { taskExecutionCount++ }
57
+
58
+ val schedulerJob = startInfiniteScheduler(interval = 500L , task = task)
59
+ delay(1500L )
60
+
61
+ schedulerJob.cancel()
62
+ schedulerJob.join()
63
+
64
+ assertThat(taskExecutionCount).isCloseTo(3 , within(1 ))
65
+ }
66
+
67
+ @Test
68
+ fun `runWithTimeout throws TimeoutCancellationException if task exceeds timeout` (): Unit = runBlocking {
69
+ val task: suspend () -> Unit = { delay(2000L ) }
70
+ assertThrows<TimeoutCancellationException > {
71
+ runWithTimeout(timeout = 1000L , task = task)
72
+ }
73
+ }
74
+
75
+ }
0 commit comments