https://kotlinlang.org logo
#coroutines
Title
# coroutines
c

Colton Idle

05/14/2021, 2:08 AM
Really basic question here but I feel like I'm finding a lot of out of date information. How can I wait for a coroutine to finish in a test? example:
Copy code
@Test
fun `test network call`() {
    var response: Response<Projects>
    GlobalScope.async {
        response = service.getMostPopularProjects()
    }

    assertThat(response.body().popularProjectSize().toString()).isGreaterThan("1")
}
z

Zach Klippenstein (he/him) [MOD]

05/14/2021, 2:27 AM
First, don’t use
GlobalScope
. I want to change the name of this channel to #coroutines-no-globalscope
👍🏼 1
👍 3
😂 6
I assume
getMostPopularProjects
is a suspend function? Use
runBlocking
,
runBlockingTest
, or one of the other coroutine testing facilities
c

Colton Idle

05/14/2021, 2:29 AM
@Zach Klippenstein (he/him) [MOD] correct. getMost... is a suspend function. I'm guessing there's no "right"/simple answer here since you said "`runBlocking`, 
runBlockingTest
, or one of the other coroutine testing facilities"
z

Zach Klippenstein (he/him) [MOD]

05/14/2021, 2:29 AM
You don’t need to tag people in channels they’ve replied to, they automatically get notified
runBlocking
is probably the simplest answer, but the “right” answer depends on your needs.
c

Colton Idle

05/14/2021, 2:30 AM
Sorry just habit to @ the person I'm speaking to! 😅
Thanks. I'll look into that. Of course the 3 stack overflow questions on this didn't mention run blocking, they all mentioned await() which through me in a loop. Stumbled upon craig russels blog post that I'm reading through now https://craigrussell.io/2019/11/unit-testing-coroutine-suspend-functions-using-testcoroutinedispatcher/
z

Zach Klippenstein (he/him) [MOD]

05/14/2021, 2:32 AM
Also if you don’t need a result, don’t use
async
, use
launch
👍 1
c

Colton Idle

05/14/2021, 2:47 AM
For anyone following along. In my simple project I just added
Copy code
testImplementation("org.jetbrains.kotlinx:kotlinx-coroutines-test:1.4.3")
and then did this
Copy code
@Test
fun `test network call`() {
    var response: Response<Projects>
    runBlocking {
        response = service.getMostPopularProjects()
        assertThat(response.body().popularProjectSize().toString()).isGreaterThan("1")
    }
}
and everything seems to work as expected. No other setup! Thanks Zach!
e

ephemient

05/14/2021, 4:06 AM
if you're just using
runBlocking
and aren't setting any test dispatchers or using
runBlockingTest
, you don't need
kotlinx-coroutines-test
c

Colton Idle

05/14/2021, 4:42 AM
I thought about that, but I removed the dependency and then runBlocking wasn't compiling anymore. I wonder if it's because it pulls in another coroutines dep transitively. I'll play around with it though. Thanks for letting me know.
2 Views