So yes, I tried and code inside `async` only runs ...
# coroutines
a
So yes, I tried and code inside
async
only runs when I call
await
m
async
isnt’ lazy, but it is… asynchronous (shocker). So if you check immediately after calling your
registerDevice
whether the
registerDeviceForService
method has been called on
lib
, then it likely won’t be the case. A new thread is spawned, so you have to wait for the method to be called on that thread.
🙂 1
I don’t know how you’re injecting the
lib
mock into your instance, but in any case, you need to find a mechanism to suspend until `lib`’s method has been called
l
@Martin Devillers
async
does not spawn a new thread
m
@louiscad true, it dispatches to the common pool, so to a different thread…
l
@Martin Devillers It's not necessarily a different thread either
It dispatches to the
CoroutineDispatcher
it's been assigned to (
DefaultDispatcher
in the current case where you pass no parameter)
You can still use
async
for single thread operations. As long as you have suspension points, it can be useful
a
So how do you guys test
async
methods? I thought wrapping test into
runBlocking
solves the problem
m
The problem is with your mock response here. You have two options: - Set up the mock to wait until its method is called, do something then - Set up the mock so that it answers some predefined value once it’s called, without trying to verify immediately that it has been called
l
@aaverin I don't write methods that return a
Deferred
. I use
suspend fun
instead. I use
async
for parallel coroutines execution, not in place of
suspend fun
or
launch
. If you really need to return a
Deferred
, be sure to follow the recommendations here: https://github.com/Kotlin/kotlinx.coroutines/blob/master/coroutines-guide.md#async-style-functions and use
await()
to await your
Deferred
inside your coroutine launched inside
runBlocking
a
What if you know for sure that this function will, eg, go to network, and has to be async? Sometimes you don’t want to pass threading decision to a consumer of the function
@louiscad also, in my code I have
suspendCoroutine {}
. How can I test it then? If I re-write and remove
async
– this suspendCoroutine still waits forever
l
@aaverin
async
is still not the right solution in this case. Have you read this guide? https://github.com/Kotlin/kotlinx.coroutines/blob/master/coroutines-guide.md If not, you should
@aaverin In the rare cases where I need to enforce a certain
CoroutineDispatcher
inside a
suspend fun
, I use
withContext(theDispatcherIWantHere) { ... }
👍 1
If your
suspendCoroutine { ... }
doesn't resume, it's because
resume
has not be called, or because the
CoroutineDispatcher
is blocked somewhere in your code
a
well,
resume
will be called only if I will have chance to mock the response The way it usually works with RxJava, you call the method, then you catch callback on a mocked instance, and manually call that callback methods to simulate successful network response
To make it work with coroutines I need to somehow make
suspendCoroutine
return instantly so I could do the mock magic
thus my original question – how to test methods with
suspendCoroutine
?
l
I don't use objects mocking right now, so I can't tell you
g
thus my original question – how to test methods with
suspendCoroutine
?
I don’t see any problem. You call this method (probably for tests easiest way to wrap this call to runBlocking), you check result of this method