@@ -7,8 +7,12 @@ import kotlinx.coroutines.Dispatchers
77import kotlinx.coroutines.delay
88import kotlinx.coroutines.runBlocking
99import kotlinx.coroutines.withContext
10+ import kotlinx.coroutines.*
11+ import kotlinx.coroutines.channels.actor
12+ import org.junit.Assert.assertEquals
1013import org.junit.Test
1114import org.mockito.kotlin.*
15+ import java.util.*
1216
1317
1418class CoroutinesTest {
@@ -157,11 +161,107 @@ class CoroutinesTest {
157161 verify(testSubject).suspending()
158162 }
159163 }
164+
165+ @Test
166+ fun answerWithSuspendFunction () = runBlocking {
167+ val fixture: SomeInterface = mock()
168+
169+ whenever(fixture.suspendingWithArg(any())).willAnswer {
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()) } willAnswer {
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())).willAnswer {
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())).willAnswer {
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()).willAnswer {
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()).willAnswer {
244+ job.join()
245+ 5
246+ }
247+
248+ val asyncTask = async {
249+ fixture.suspending()
250+ }
251+
252+ // TODO: on coroutines >1.3 it should be job.complete()
253+ job.cancel()
254+
255+ withTimeout(100 ) {
256+ assertEquals(5 , asyncTask.await())
257+ }
258+ }
160259}
161260
162261interface SomeInterface {
163262
164263 suspend fun suspending (): Int
264+ suspend fun suspendingWithArg (arg : Int ): Int
165265 fun nonsuspending (): Int
166266}
167267
0 commit comments