Need help with a test... (still new to the world o...
# coroutines
c
Need help with a test... (still new to the world of testing coroutines) Here's something I've come across a bunch
Copy code
@Test
  fun `assert foo`() = runTest{
    val bar = Bar(coroutineContext)
    bar.sync()
    assertThat(bar.state.sync).isEqualTo("bla")
  }
Bar has sync defined as
Copy code
fun syncConfig() {
    passedInScope.launch {
      state = "bla"
    }
  }
so. basically. can i do something like this?
Copy code
@Test
  fun `assert foo`() = runTest{
    val bar = Bar(coroutineContext)
    bar.sync()
    coroutineContext.waitTillAllWorkIsDone() <==== the additional line
    assertThat(bar.state.sync).isEqualTo("bla")
  }
f
You have 2 ways to go about this: • refactor
sync
to be a
suspend
function (that'd be my preferred way, having methods that launch and forget lead to issues) • have the
passedInScope
provided to whatever class includes
syncConfig
and in tests pass a test scope, either
coroutineContext
from
runTest
,
backgroundScope
from
runTest
or some other scope you can control
you can also return the
job
from
syncConfig
and then
join
that
a
Adding
testScheduler.advanceUntilIdle()
after
bar.sync()
should make it work I believe.
If you would like
launch
and
async
calls to be executed automatically, you can also use
runTest(UnconfinedTestDispatcher())
.
c
Oooh!
advanceUntilIdle
worked!
I'm going to try to parse out all of the other suggestions here to see if I'm doing anything "wrong".
• refactor
sync
to be a
suspend
function (that'd be my preferred way, having methods that launch and forget lead to issues)
I think I'd like to do that, but my code above is actually a viewModel. So the videwModel has a function that fires a call and then updates some compose snapshot state. so all of the recs I've seen before say that not exposing a suspend fun in ViewModel is a good idea.
• have the
passedInScope
provided to whatever class includes
syncConfig
and in tests pass a test scope, either
coroutineContext
from
runTest
,
backgroundScope
from
runTest
or some other scope you can control
Yeah, that's what I'm doing now. PassedInScope == coroutineContext from
val bar = Bar(coroutineContext)
sorry that I didn't make that clear enough. 🤦
If you would like
launch
and
async
calls to be executed automatically, you can also use
runTest(UnconfinedTestDispatcher())
.
@Albert Chang hm. I don't think I follow.
c
gracias!
thanks for the push to read those docs. some things definitely seem clearer now. not 100%, but im getting there 🙏