@@ -7,8 +7,12 @@ import kotlinx.coroutines.Dispatchers
7
7
import kotlinx.coroutines.delay
8
8
import kotlinx.coroutines.runBlocking
9
9
import kotlinx.coroutines.withContext
10
+ import kotlinx.coroutines.*
11
+ import kotlinx.coroutines.channels.actor
12
+ import org.junit.Assert.assertEquals
10
13
import org.junit.Test
11
14
import org.mockito.kotlin.*
15
+ import java.util.*
12
16
13
17
14
18
class CoroutinesTest {
@@ -157,11 +161,106 @@ class CoroutinesTest {
157
161
verify(testSubject).suspending()
158
162
}
159
163
}
164
+
165
+ @Test
166
+ fun answerWithSuspendFunction () = runBlocking {
167
+ val fixture: SomeInterface = mock()
168
+
169
+ whenever(fixture.suspendingWithArg(any())).doSuspendableAnswer {
170
+ withContext(Dispatchers .Default ) { it.getArgument<Int >(0 ) }
171
+ }
172
+
173
+ assertEquals(5 , fixture.suspendingWithArg(5 ))
174
+ }
175
+
176
+ @Test
177
+ fun inplaceAnswerWithSuspendFunction () = runBlocking {
178
+ val fixture: SomeInterface = mock {
179
+ onBlocking { suspendingWithArg(any()) } doSuspendableAnswer {
180
+ withContext(Dispatchers .Default ) { it.getArgument<Int >(0 ) }
181
+ }
182
+ }
183
+
184
+ assertEquals(5 , fixture.suspendingWithArg(5 ))
185
+ }
186
+
187
+ @Test
188
+ fun callFromSuspendFunction () = runBlocking {
189
+ val fixture: SomeInterface = mock()
190
+
191
+ whenever(fixture.suspendingWithArg(any())).doSuspendableAnswer {
192
+ withContext(Dispatchers .Default ) { it.getArgument<Int >(0 ) }
193
+ }
194
+
195
+ val result = async {
196
+ val answer = fixture.suspendingWithArg(5 )
197
+
198
+ Result .success(answer)
199
+ }
200
+
201
+ assertEquals(5 , result.await().getOrThrow())
202
+ }
203
+
204
+ @Test
205
+ fun callFromActor () = runBlocking {
206
+ val fixture: SomeInterface = mock()
207
+
208
+ whenever(fixture.suspendingWithArg(any())).doSuspendableAnswer {
209
+ withContext(Dispatchers .Default ) { it.getArgument<Int >(0 ) }
210
+ }
211
+
212
+ val actor = actor<Optional <Int >> {
213
+ for (element in channel) {
214
+ fixture.suspendingWithArg(element.get())
215
+ }
216
+ }
217
+
218
+ actor.send(Optional .of(10 ))
219
+ actor.close()
220
+
221
+ verify(fixture).suspendingWithArg(10 )
222
+
223
+ Unit
224
+ }
225
+
226
+ @Test
227
+ fun answerWithSuspendFunctionWithoutArgs () = runBlocking {
228
+ val fixture: SomeInterface = mock()
229
+
230
+ whenever(fixture.suspending()).doSuspendableAnswer {
231
+ withContext(Dispatchers .Default ) { 42 }
232
+ }
233
+
234
+ assertEquals(42 , fixture.suspending())
235
+ }
236
+
237
+ @Test
238
+ fun willAnswerWithControlledSuspend () = runBlocking {
239
+ val fixture: SomeInterface = mock()
240
+
241
+ val job = Job ()
242
+
243
+ whenever(fixture.suspending()).doSuspendableAnswer {
244
+ job.join()
245
+ 5
246
+ }
247
+
248
+ val asyncTask = async {
249
+ fixture.suspending()
250
+ }
251
+
252
+ job.complete()
253
+
254
+ withTimeout(100 ) {
255
+ assertEquals(5 , asyncTask.await())
256
+ }
257
+ }
160
258
}
161
259
162
260
interface SomeInterface {
163
261
164
262
suspend fun suspending (): Int
263
+ suspend fun suspendingWithArg (arg : Int ): Int
165
264
fun nonsuspending (): Int
166
265
}
167
266
0 commit comments