'Kotlin Coroutines for fetching from raw.githubusercontents.com

I am currently working on porting a Kotlin library to Kotlin/Js. I am currently struggling with how to fetch something from the web. I want to retrieve a page from raw.githubusercontent.com (example).

My code currently looks like this:

// function
fun getText(url: String): String? {
    val url = "some url"
    var text: String? = null
    GlobalScope.launch {
        text = window.fetch(url).await().body.toString()
    }
    return text
}

//test
@Test
fun run_test() = runTest {
    val text = getText(url)
    assertNotNull(text)
}

But I never seem to get the code in the Coroutine executed when running my unit tests. It's my first time working with coroutines, so I am not too familiar with them.

Have a nice day



Solution 1:[1]

By using the GlobalScope you've broke the structured concurrency. Try to avoid it.

Your window.fetch just runs in the topmost scope, so your test (runTest) doesn't wait for it's completion. It's like a daemon thread.

I would try to rewrite it to something like:

suspend fun getText(url: String): String? {
    val url = "some url"
    val text = window.fetch(url).await().body.toString()

    return text
}

//test
@Test
fun run_test() = runTest {
    val text = getText(url)
    assertNotNull(text)
}

Well, if it's an interface, it means that you:

  • Cannot change the parameters of the method (i.e. pass the scope)
  • Cannot make it an extension function (i.e. on the scope)
  • Cannot add suspend modifier

the only solution you probably have is to use runBlocking:

fun getText(url: String): String? {
    val url = "some url"
    val text = runBlocking {
        window.fetch(url).await().body.toString()
    }

    return text
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1