-
Notifications
You must be signed in to change notification settings - Fork 1.9k
Integrate test dispatchers with libraries using Dispatchers.Xxx #1365
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
The plan is to make |
Any update on this issue ? |
I too am curious if there's any update on this issue in 2020. Looking into solutions for unit testing |
Why don't you want users to provide your own dispatcher? Any solution here would basically be just another way to replace default dispatcher (just limited to the test library that could be used in production by your users). |
You can still use dependency injection without exposing to your consumers. E.g. an internal primary constructor that takes a Dispatcher, and a public secondary constructor that provides a default value. Or a public interface with internal implementation and a public factory function. |
@zach-klippenstein This solution does not help me with hardcoded |
Another potential approach to this problem, which still avoids overriding global singletons, would be to bake something like what is proposed in this article into the standard library, and change |
This approach still requires you to have access to the scope/context. If library creates its scope internally, you cannot access that. |
This issue keeps coming up for me. Is there anything we can do to help move it along? |
This is (partially?) fixed now in 1.6.0-RC with the new API for testing.
I'm not sure how much of a problem the remaining limitation is in practice: is it often that third-party code delays for long enough to notice? So, not closing this issue yet. Please share your thoughts and feedback! |
We do have retry handling and other code that needs to work around limitations of underlying libraries with Also, it would be really awesome to have some utility to make setting up coroutine-capable unit tests trivially easy. Ideally, the default behavior in unit tests would automatically switch all dispatchers and the test lib would provide a global singleton default If having nice default behavior automatically is impossible, then it would be great to have something like a CoroutineTest base class or delegate or a test rule that can be added to any existing test class in as little code as possible to get the nice defaults. Anything that doesn't require repeating that boilerplate and learning unnecessary details just to get started would be great. |
Could anyone explain more about what he is saying for me? |
@dkhalanskyjb AFAIS the main problem is still there, which is that using hard-coded Exploiting the Example of the current problem as far as I see that: class DispatchersTest {
private val dispatcher = UnconfinedTestDispatcher()
@Test
fun `a non-deterministic test`(): Unit = runTest {
spinHardcoded() // Sometimes fails and slow
}
@Test
fun `a deterministic test`(): Unit = runTest(dispatcher) {
spinInjected(dispatcher) // Deterministic and fast
}
suspend fun spinHardcoded() =
withContext(Dispatchers.IO) { spinTheWheel() }
suspend fun spinInjected(dispatcher: CoroutineDispatcher) =
withContext(dispatcher) { spinTheWheel() }
suspend fun spinTheWheel() = coroutineScope {
var state: Int
repeat(100000) { index ->
launch {
state = index
check(state == index)
}
}
}
} |
Not a very illustrating example. So, our goal is twofold:
Making Another issue with mocking val connection = try {
withTimeout(20.seconds) {
database.connect()
}
} catch (e: TimeoutCancellationException) {
throw IllegalStateException("Couldn't connect to the database")
} The reason is, those 20 seconds will pass instantly with the test framework, so the code will always time out. We would need a way for the author to say "I need to use |
Thank you for your answer! What you say makes sense to me.
Regarding the database example issue, I see the problem and the problem it could be with third-party libraries. |
Thank you very much, this hack solve my issue |
Make sure that libraries can use hard-coded
withContext(Dispatchers.IO) { ... }
and still be testable with test dispatchers. See also discussion in #810 and #1202.The text was updated successfully, but these errors were encountered: