Git Product home page Git Product logo

Comments (3)

dkhalanskyjb avatar dkhalanskyjb commented on June 11, 2024 1

Yes, that's better, thanks.

For testing coroutines on Android, the recommended approach is to inject the scope: https://developer.android.com/kotlin/coroutines/test#inject-scope This way, you can use viewModelScope in production, but during testing, pass backgroundScope and have the work properly cancelled.

In the "setting the Main dispatcher" section, one-shot operations are shown, ones that perform some task and then finish. For testing such tasks, just setting the main dispatcher is fine. When a task in a viewModelScope outlives the test, you need to cancel it somehow, and injecting the scope becomes mandatory.

The reason repro hangs but noRepro doesn't is that the test dispatcher always knows it still has extra things to do in the repro case (that is, check every 300 ms for new elements), but in the noRepro case, it sees that there is no more work to execute and finishes, even though some coroutines are still running and weren't cleaned up.

from kotlinx.coroutines.

dkhalanskyjb avatar dkhalanskyjb commented on June 11, 2024

Both of these tests are written incorrectly, because they break structured concurrency. Manually creating a CoroutineScope, passing the dispatcher to it, can lead to various issues; in this case, the coroutine simply will leak without completing. For example, in CoroutineScope(dispatcher).launch { try { flow.collect { } } finally { println("cleaning up resources") } }, the resources won't get cleaned up.

A correct test would be something like this:

  @Test
  fun noRepro() = runTest {
    val flow = MutableSharedFlow<Int>()
    backgroundScope.launch {
      flow.collect {}
    }
  }

from kotlinx.coroutines.

mhernand40 avatar mhernand40 commented on June 11, 2024

Thank you for your reply @dkhalanskyjb. But if both tests are written incorrectly, shouldn't both of them hang? My concern is that there are probably plenty of Android ViewModel tests that are being written incorrectly even though they are following the documentation for Testing Kotlin coroutines on Android, particularly the section Setting the Main dispatcher.

Here is a more realistic example that hopefully conveys what I am getting at:

class ReproViewModel : ViewModel() {
  private val flow = MutableSharedFlow<Int>()

  init {
    viewModelScope.launch {
      flow
        .sample(300L) // Test on longer hangs if you comment out this line
        .collect {}
    }
  }
}

class ReproTest {

  // Normally this @Before/@After would be extracted out into a reusable JUnit rule.
  @Before
  fun setUp() {
    Dispatchers.setMain(StandardTestDispatcher())
  }

  @After
  fun tearDown() {
    Dispatchers.resetMain()
  }

  @Test
  fun repro() = runTest {
    ReproViewModel()
  }
}

from kotlinx.coroutines.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.