Open dalewking opened 3 weeks ago
Later realized I can use deferred[self]
I added these functions which handle the delaying for me, but would be nice to have it built in:
infix fun <T> SuspendAnsweringScope<in Result<T>>.returnsSuccessBy(block: () -> T) {
calls {
try { success(block()) } finally { deferred[self]?.await() }
}
}
infix fun <T> SuspendAnsweringScope<T>.callsDelayable(
block: suspend SuspendCallDefinitionScope<T>.(CallArgs) -> T,
) {
calls {
try { block(this, it) } finally { deferred[self]?.await() }
}
}
I'm considering implementing a set of coroutine-related utilities, and such a util might be a part of that set. However, it would require changing kotlinx.coroutines
to an api
dependency. Before that I need to consider how it should be done.
Currently, Mokkery depends internally on coroutines - as an implementation
dependency. I see 3 possible options:
implementation
to api
and add coroutine utils to runtime. This option is easier, but I'm not sure if it's good.Anyway, until I have this figured, any part of public API that uses coroutines API is kind of blocked.
I personally prefer 3rd option, moving all coroutines related stuff to a separate optional library called maybe like mockkery-coroutine-extension
that user can optionally implement
. MVIKotlin is one example library that does this. The core mvikotlin
module doesn't have any coroutine related stuff, but the mvikotlin-extensions-coroutines
does. Alternativelly, one can use mvikotlin-extensions-reaktive
if coroutine is not the favourite
It's blocked by #7. Currently, wasm wasi support without coroutines causes some complications in the coroutines setup. With coroutines 1.9.0 release it will be simpler and then I can think about extracting coroutines module.
@dalewking my API proposal for your use case:
val deferred = CompletableDeferred<Int>()
everySuspend { mock.bar() } awaits deferred
launch { sut.load() }
assertTrue(sut.isLoading)
deferred.complete(1)
assertFalse(sut.isLoading)
What do you think?
Sometimes you need to test a state that is present while a suspending call is being made. For example, loading is true while the suspending call is still being executed.
So you need a way to have a mocked suspend function not return immediately but only return when you tell it to. Here is the way i am handling it now, but it would be nice to have support for this built-in
I created a mutable map to record what calls are being blocked:
Then in any suspend mock set up that i need to support blocking I have to do this (In this case it is a
fun interface
being mocked):This then lets me do tests like this: