-
Notifications
You must be signed in to change notification settings - Fork 1
/
TestingTimeoutInSeparateCoroutine.kt
116 lines (95 loc) · 2.73 KB
/
TestingTimeoutInSeparateCoroutine.kt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
import api.User
import api.UserRepo
import api.UserService
import coroutines.coAssertThrows
import io.mockk.clearAllMocks
import io.mockk.coEvery
import io.mockk.coVerify
import io.mockk.mockk
import kotlinx.coroutines.*
import kotlinx.coroutines.test.runBlockingTest
import org.junit.jupiter.api.Assertions.assertSame
import org.junit.jupiter.api.Assertions.assertTrue
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
fun CoroutineScope.loadUserAsync(backend: UserService):Deferred<User> = async {
withTimeout(30_000) {
backend.load()
}
}
fun CoroutineScope.loadUserLaunch(backend: UserService):Job = launch {
withTimeout(30_000) {
backend.load()
}
}
/**
* Testing timeout in new coroutines is quites similar to
* testing in [suspendable functions][TestingTimeoutInSuspendableFunction]
*/
class TestingTimeoutInSeparateCoroutine {
private val backend: UserService = mockk()
private val repo: UserRepo = mockk()
private val user = User("Herbert")
@BeforeEach
fun setUp() {
clearAllMocks()
}
@Test
fun `testing async in time`() = runBlockingTest {
coEvery { backend.load() } coAnswers {
delay(29_999)
user
}
val deferred = loadUserAsync(backend)
// waiting will advance coroutine
val loaded = deferred.await()
assertSame(user, loaded)
}
@Test
fun `testing async timeout`() = runBlockingTest {
coEvery { backend.load() } coAnswers {
delay(30_000)
user
}
coAssertThrows<TimeoutCancellationException> {
loadUserAsync(backend).await()
}
}
@Test
fun `testing launch timeout`() = runBlockingTest {
coEvery { backend.load() } coAnswers {
delay(30_000)
user
}
val job = loadUserLaunch(backend)
job.join()
// join() does not throw CancellationException
assertTrue(job.isCancelled)
}
@Test
fun `testing behaviour using mocks`() = runBlockingTest {
coEvery { backend.load() } coAnswers {
delay(29_999)
user
}
loadUserToRepo(backend, repo)
advanceUntilIdle()
coVerify { repo.store(user) }
}
@Test
fun `testing behaviour on timeout using mocks`() = runBlockingTest {
coEvery { backend.load() } coAnswers {
delay(30_000)
user
}
loadUserToRepo(backend, repo)
advanceUntilIdle()
coVerify(exactly = 0) { repo.store(user) }
}
}
fun CoroutineScope.loadUserToRepo(backend: UserService, repo: UserRepo) = launch {
val user = withTimeout(30_000) {
backend.load()
}
repo.store(user)
}