dave08
03/01/2020, 5:53 PM@get:Rule
val instantTaskExecutorRule = InstantTaskExecutorRule()
and
shadowOf(Looper.getMainLooper()).idle()
when I try
someLiveData.asFlow().first()
it just stays stuck with runBlocking and crashes with runBlockingTest...Anastasia Finogenova
03/01/2020, 6:45 PMAnastasia Finogenova
03/01/2020, 6:46 PMAhmed Ibrahim
03/01/2020, 9:41 PMDispatchers.setMain
available in kotlinx-coroutines-test
lib. That way you override Dispatchers.Main which the viewModelScope uses.
You can take a look there and I think you'll get what I mean.
https://gist.github.com/manuelvicnt/049ce057fa6b5e5c785ec9fff7c22a7cAnastasia Finogenova
03/01/2020, 10:02 PMghedeon
03/02/2020, 12:40 AMsetMain()
and runBlocking()
is enough to synchronize the execution.Anastasia Finogenova
03/02/2020, 1:26 AMAnastasia Finogenova
03/02/2020, 1:43 AMrkeazor
03/02/2020, 6:28 AMghedeon
03/02/2020, 7:13 AMdave08
03/02/2020, 11:59 AMdave08
03/02/2020, 12:25 PMsuspend fun <A : Activity> AccountManager.addAccount(activity: A?, accountType: String, authTokenType: String, options: Bundle? = null) =
callAsync<Bundle> { callback -> addAccount(accountType, authTokenType, null, options, activity, callback, null) }
/**
* Callback class that uses a continuation as the callback for the account manager. Note that
* this callback is NOT designed to survive the destruction of the [Context] ([Activity]).
*
* @property cont The continuation that will be invoked on completion.
*/
class CoroutineAccountManagerCallback<T>(private val cont: CancellableContinuation<T>) : AccountManagerCallback<T> {
@UseExperimental(InternalCoroutinesApi::class)
override fun run(future: AccountManagerFuture<T>) {
try {
if (future.isCancelled) {
cont.cancel()
} else {
cont.resume(future.result)
}
} catch (e: Exception) {
if (e is CancellationException) {
cont.cancel(e)
} else {
cont.tryResumeWithException(e)
}
}
}
}
/**
* Helper function that helps with calling account manager operations asynchronously.
*
* @receiver The account manager. This is actually not stable.
*/
@Deprecated("Use a special ContextCoroutine that doesn't put a context in the capture", ReplaceWith("callAccountManagerAsync(context, operation)"))
suspend inline fun <R> AccountManager.callAsync(crossinline operation: AccountManager?.(CoroutineAccountManagerCallback<R>) -> Unit): R {
return suspendCancellableCoroutine<R> { cont ->
operation(CoroutineAccountManagerCallback(cont))
}
}
I'm using the CoroutinesTestRule above, and shadowMainLooper.idle()... maybe the above code is wrong (or not compatible with Robolectric's ShadowAccountManager? I took it from a Github repo somewhere...Anastasia Finogenova
03/02/2020, 5:32 PM