-
Notifications
You must be signed in to change notification settings - Fork 1.9k
What is the preferred way of testing when the code being tested launches a never-ending coroutine? #3283
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
Creating a scope for neverending jobs and cancelling it in the end is the recommended way. You may be interested in this as well, it looks fairly similar to your question: #1531 tl;dr: |
We did it this way: we have injectable CoroutineScope (appScope~GlobalScope) for app-lifetime jobs, this caused us issues in our unit tests, so we had to rewrite runBlockingTest somehow like this. (appScope is injected through constructor to the tested class) private val testScope: TestScope = TestScope()
protected val appScope: CoroutineScope = CoroutineScope(testScope.coroutineContext + SupervisorJob())
protected fun runBlockingTest(
body: suspend TestScope.() -> Unit,
): TestResult = testScope.runTest {
body()
appScope.coroutineContext[Job.Key]!!.cancelAndJoin()
} |
@dkhalanskyjb Thanks for such a quick response 🙏 I supposed this is going to be the answer. However, I must admit that I somewhat agree with the last comment here. It seems like a lot of unnecessary hassle to create and close an additional scope in these cases, but I understand there must have been some good reasons for the current design of One of my questions was hidden in the code snippet so let me repeat it because I feel like it wasn't answered yet: is it really necessary to call |
In the provided code, when the dispatcher is mocked, no, the coroutines will not leak, there's no global state related to the test framework. In general, though, it's absolutely possible to have thousands of dangling coroutines; the simplest way to get this is to do |
Thanks for the explanation 👍 I guess we can close this issue now 🙂 |
What is the preferred way of unit testing classes which internally launch a never-ending coroutine such as
SharedFlow
collection?Let’s say:
If I use
runTest
and pass the createdTestScope
then the test is going to fail after some time because there is a running coroutine.So should I create another scope instead? Like this, for example?
I'm trying to figure out what are the best practices in such cases.
The text was updated successfully, but these errors were encountered: