title: Coroutines - unit testing viewModelScope.launch methods
body: <p>I am writing unit tests for my viewModel, but having trouble executing the tests. The <code>runBlocking { ... }</code> block doesn't actually wait for the code inside to finish, which is surprising to me.</p>
  
  <p>The test fails because <code>result</code> is <code>null</code>. Why doesn't <code>runBlocking { ... }</code> run the <code>launch</code> block inside the ViewModel in blocking fashion?</p>
  
  <p>I know if I convert it to a <code>async</code> method that returns a <code>Deferred</code> object, then I can get the object by calling <code>await()</code>, or I can return a <code>Job</code> and call <code>join()</code>. <strong>But</strong>, I'd like to do this by leaving my ViewModel methods as <code>void</code> functions, is there a way to do this?</p>
  
  <pre><code>// MyViewModel.kt
  
  class MyViewModel(application: Application) : AndroidViewModel(application) {
  
      val logic = Logic()
      val myLiveData = MutableLiveData&lt;Result&gt;()
  
      fun doSomething() {
          viewModelScope.launch(MyDispatchers.Background) {
              System.out.println("Calling work")
              val result = logic.doWork()
              System.out.println("Got result")
              myLiveData.postValue(result)
              System.out.println("Posted result")
          }
      }
  
      private class Logic {
          suspend fun doWork(): Result? {
            return suspendCoroutine { cont -&gt;
                Network.getResultAsync(object : Callback&lt;Result&gt; {
                        override fun onSuccess(result: Result) {
                            cont.resume(result)
                        }
  
                       override fun onError(error: Throwable) {
                            cont.resumeWithException(error)
                        }
                    })
            }
      }
  }
  </code></pre>
  
  <pre><code>// MyViewModelTest.kt
  
  @RunWith(RobolectricTestRunner::class)
  class MyViewModelTest {
  
      lateinit var viewModel: MyViewModel
  
      @get:Rule
      val rule: TestRule = InstantTaskExecutorRule()
  
      @Before
      fun init() {
          viewModel = MyViewModel(ApplicationProvider.getApplicationContext())
      }
  
      @Test
      fun testSomething() {
          runBlocking {
              System.out.println("Called doSomething")
              viewModel.doSomething()
          }
          System.out.println("Getting result value")
          val result = viewModel.myLiveData.value
          System.out.println("Result value : $result")
          assertNotNull(result) // Fails here
      }
  }
  
  </code></pre>