question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

blocking corountine scope

See original GitHub issue

Hi in order to simplify unit testing I am trying to get changable context of the Corountene context like below (I am able to change context from test method) object MyGlobalContext : CoroutineScope { var context : CoroutineContext = Dispatchers.Default override val coroutineContext: CoroutineContext get() = context } Hovewer I am wondering weather it is possible to make averything created on the MyGlobalContext (like MyGlobalContext.launch; MyGlobalContext.actor etc) to run as runBlocking in order to make the methods synchronous for test purposes?

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Comments:6 (3 by maintainers)

github_iconTop GitHub Comments

1reaction
wyaeldcommented, Sep 11, 2019

Here are 2 examples below that show you what you can do, hopefully that helps.

The issue you are seeing is that your assertEquals is not going to wait for the coroutine to have completed. Also you can problems for yourself modifying state outside a coroutine unless you are using the correct patterns to do so.

    @Test
    fun `corountine scope dispatcher unconfined 1`() {

        var context: CoroutineContext = Dispatchers.Unconfined
        val scope = CoroutineScope(context)
        var x = 0


        var job = scope.launch {
            delay(100);
            x++
        }

        runBlocking {
            withTimeout(200) {
                job.join()
                assertThat(x).isEqualTo(1)
            }
        }
    }

    @Test
    fun `corountine scope dispatcher unconfined 2`(){
        var context : CoroutineContext = Dispatchers.Unconfined
        val scope = CoroutineScope(context)
        val x = 0

        runBlocking {

            var result = scope.async {
                delay(100)
                x+1 }

            withTimeout(200) {
                val returned = result.await()
                assertThat(returned).isEqualTo(1)
            }
        }

    }
1reaction
zach-klippensteincommented, Aug 30, 2019

This is exactly why the concept of a “global scope” is discouraged. If you change your TestClass to inject the dispatcher or context to use via the constructor, like so:

class TestClass(private val context: CoroutineContext) {
  private val scope = CoroutineScope(context)
  var number = 1

  fun addOne() {
    scope.launch { number++ }
  }
}

Then your test can simply inject Dispatchers.Unconfined and you’ll have the behavior you’re looking for:

@Test
fun test1() {
  val cl = TestClass(Dispatchers.Unconfined)
  cl.addOne()
  assertEquals(cl.number, 2)
}
Read more comments on GitHub >

github_iconTop Results From Across the Web

Coroutines: runBlocking vs. coroutineScope - Baeldung
Both runBlocking and coroutineScope are coroutine builders, which means they are used to launch coroutines, but we use them in different ...
Read more >
Coroutines: runBlocking vs coroutineScope - Stack Overflow
runBlocking is a low-level construct, to be used only in framework code or self-contained examples like yours. · coroutineScope is a user-facing ...
Read more >
Coroutines basics - Kotlin
The main difference is that the runBlocking method blocks the current thread for waiting, while coroutineScope just suspends, releasing the ...
Read more >
runBlocking in Kotlin Coroutines with Example - GeeksforGeeks
Runs a new coroutine and blocks the current thread interruptible until its completion. This function should not be used from a coroutine.
Read more >
Kotlin Coroutines: coroutineScope vs. runBlocking (Tutorial)
To keep it simple: runBlocking blocks, and coroutineScope suspends, and for that reason, runBlocking is a normal function, ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found