title: Android Kotlin Unit test failing with io.mockk.MockKException: no answer found for
body: <p>EDIT: For future readers. I don't know if this question will help you very much.The logic of the fun has changed drastically so I am closing the question, but won't delete it. </p>
  
  <p>I am trying to write some unit tests for my ViewModel. I am using Mockk and Junit5. </p>
  
  <p>What should happen: 
  The mockked repository returns fakeresponse, I call the fun in the VM, it sets the livedata to be the fake response data.</p>
  
  <p>What actually happens: </p>
  
  <pre><code>Exception in thread "DefaultDispatcher-worker-2 @coroutine#1" io.mockk.MockKException: no answer found for: DrillRepository(#1).loadDrillTypes()
      at io.mockk.impl.stub.MockKStub.defaultAnswer(MockKStub.kt:90)
      at io.mockk.impl.stub.MockKStub.answer(MockKStub.kt:42)
      at io.mockk.impl.recording.states.AnsweringState.call(AnsweringState.kt:16)
      at io.mockk.impl.recording.CommonCallRecorder.call(CommonCallRecorder.kt:53)
      at io.mockk.impl.stub.MockKStub.handleInvocation(MockKStub.kt:263)
      at io.mockk.impl.instantiation.JvmMockFactoryHelper$mockHandler$1.invocation(JvmMockFactoryHelper.kt:25)
      at io.mockk.proxy.jvm.advice.Interceptor.call(Interceptor.kt:20)
      at com.nikolam.basketpro.data.DrillRepository.loadDrillTypes(DrillRepository.kt:11)
      at com.nikolam.basketpro.ui.drills.selection.DrillsSelectionViewModel$fetchDrillTypes$1.invokeSuspend(DrillsSelectionViewModel.kt:41)
      at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
      at kotlinx.coroutines.DispatchedTask.run(Dispatched.kt:241)
      at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:594)
      at kotlinx.coroutines.scheduling.CoroutineScheduler.access$runSafely(CoroutineScheduler.kt:60)
      at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:740)
  
  org.opentest4j.AssertionFailedError: 
  Expected :[DrillsType(drillType_title=title1, drillType_imageUrl=url1), DrillsType(drillType_title=title2, drillType_imageUrl=url2)]
  Actual   :null
  &lt;Click to see difference&gt;
  
  
      at org.junit.jupiter.api.AssertionUtils.fail(AssertionUtils.java:55)
      at org.junit.jupiter.api.AssertionUtils.failNotEqual(AssertionUtils.java:62)
      at org.junit.jupiter.api.AssertEquals.assertEquals(AssertEquals.java:182)
      at org.junit.jupiter.api.AssertEquals.assertEquals(AssertEquals.java:177)
      at org.junit.jupiter.api.Assertions.assertEquals(Assertions.java:1124)
      at com.nikolam.basketpro.ui.drills.selection.DrillsSelectionViewModelTest.drillTypeListWillBePopulatedOnSuccess(DrillsSelectionViewModelTest.kt:43)
      at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
      at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
      at java.lang.reflect.Method.invoke(Method.java:498)
      at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:686)
      at org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60)
      at org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java:131)
      at org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:149)
      at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestableMethod(TimeoutExtension.java:140)
      at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestMethod(TimeoutExtension.java:84)
      at org.junit.jupiter.engine.execution.ExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod$0(ExecutableInvoker.java:115)
      at org.junit.jupiter.engine.execution.ExecutableInvoker.lambda$invoke$0(ExecutableInvoker.java:105)
      at org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:106)
      at org.junit.jupiter.engine.execution.InvocationInterceptorChain.proceed(InvocationInterceptorChain.java:64)
      at org.junit.jupiter.engine.execution.InvocationInterceptorChain.chainAndInvoke(InvocationInterceptorChain.java:45)
      at org.junit.jupiter.engine.execution.InvocationInterceptorChain.invoke(InvocationInterceptorChain.java:37)
      at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:104)
      at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:98)
      at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$6(TestMethodTestDescriptor.java:205)
      at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
      at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:201)
      at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:137)
      at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:71)
      at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:135)
      at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
      at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125)
      at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135)
      at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123)
      at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
      at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122)
      at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80)
      at java.util.ArrayList.forEach(ArrayList.java:1257)
      at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
      at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:139)
      at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
      at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125)
      at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135)
      at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123)
      at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
      at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122)
      at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80)
      at java.util.ArrayList.forEach(ArrayList.java:1257)
      at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
      at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:139)
      at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
      at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125)
      at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135)
      at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123)
      at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
      at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122)
      at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80)
      at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:32)
      at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
      at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:51)
      at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:248)
      at org.junit.platform.launcher.core.DefaultLauncher.lambda$execute$5(DefaultLauncher.java:211)
      at org.junit.platform.launcher.core.DefaultLauncher.withInterceptedStreams(DefaultLauncher.java:226)
      at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:199)
      at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:132)
      at com.intellij.junit5.JUnit5IdeaTestRunner.startRunnerWithArgs(JUnit5IdeaTestRunner.java:69)
      at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
      at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
      at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
  </code></pre>
  
  <p>This is the test</p>
  
  <pre><code>@ExtendWith(value = [InstantExecutorExtension::class, TestSchedulerExtension::class])
  internal class DrillsSelectionViewModelTest{
  
      val mockkDrillRepository = mockk&lt;DrillRepository&gt;()
  
      lateinit var drillsSelectionViewModel : DrillsSelectionViewModel
  
      @BeforeEach
      fun setup(){
  
          drillsSelectionViewModel = DrillsSelectionViewModel(mockkDrillRepository)
  
          val fakeResponse = Observable.just(DrillsType("title1", "url1"), DrillsType("title2","url2"))
  
  
          every{ mockkDrillRepository.loadDrillTypes()} returns fakeResponse
  
      }
  
      @Test
      fun `should update the livedata with correct data from the repository`(){
  
          drillsSelectionViewModel.fetchDrillTypes()
  
          assertEquals(arrayListOf(DrillsType("title1", "url1"), DrillsType("title2","url2")), getValue(drillsSelectionViewModel.drillsTypeList.value))
  
      }
  
  }
  </code></pre>
  
  <p>These are the two classes that are extended in the test</p>
  
  <pre><code>class InstantExecutorExtension : BeforeEachCallback, AfterEachCallback {
  
      override fun beforeEach(context: ExtensionContext?) {
          ArchTaskExecutor.getInstance().setDelegate(object : TaskExecutor() {
              override fun executeOnDiskIO(runnable: Runnable) {
                  runnable.run()
              }
  
              override fun postToMainThread(runnable: Runnable) {
                  runnable.run()
              }
  
              override fun isMainThread(): Boolean {
                  return true
              }
          })
      }
  
      override fun afterEach(context: ExtensionContext?) {
          ArchTaskExecutor.getInstance().setDelegate(null)
      }
  
  }
  </code></pre>
  
  <pre><code>class TestSchedulerExtension : BeforeTestExecutionCallback, AfterTestExecutionCallback {
  
      override fun beforeTestExecution(context: ExtensionContext?) {
          RxJavaPlugins.setIoSchedulerHandler { Schedulers.trampoline() }
          RxJavaPlugins.setComputationSchedulerHandler { Schedulers.trampoline() }
          RxJavaPlugins.setNewThreadSchedulerHandler { Schedulers.trampoline() }
          RxAndroidPlugins.setMainThreadSchedulerHandler { Schedulers.trampoline() }
      }
  
      override fun afterTestExecution(context: ExtensionContext?) {
          RxJavaPlugins.reset()
          RxAndroidPlugins.reset()
      }
  
  }
  </code></pre>
  
  <p>This is the SUT</p>
  
  <pre><code>class DrillsSelectionViewModel(private val repository: DrillRepository): ViewModel() {
  
      private val compositeDisposable = CompositeDisposable()
  
      private var _drillsTypeList = MutableLiveData&lt;ArrayList&lt;DrillsType&gt;&gt;()
      val drillsTypeList: LiveData&lt;ArrayList&lt;DrillsType&gt;&gt;
          get() = _drillsTypeList
  
  
      init{
  
          fetchDrillTypes()
      }
  
      fun fetchDrillTypes()
      {
  
          val list = ArrayList&lt;DrillsType&gt;()
  
          viewModelScope.launch(Dispatchers.IO) {
              compositeDisposable += repository.loadDrillTypes()
                  .subscribeWith(object : DisposableObserver&lt;DrillsType&gt;() {
  
                      override fun onError(e: Throwable) {
                          Log.d("TAG", e?.message)
                      }
  
                      override fun onNext(data: DrillsType) {
                          Log.d("TAG", "data is " + data.toString())
                          list.add(data)
                      }
  
                      override fun onComplete() {
                          Log.d("TAG", "COMPLETE")
                          _drillsTypeList.postValue(list)
                      }
                  })
          }
      }
  
  
      override fun onCleared() {
          super.onCleared()
          if (!compositeDisposable.isDisposed) {
              compositeDisposable.dispose()
          }
      }
  
  }
  </code></pre>
  
  <p>The DOC</p>
  
  <pre><code>
  
      fun loadDrillTypes(): Observable&lt;DrillsType&gt; {
          return remoteDataSource.loadDrillTypes()
      }
  
  
      fun loadDrillList(drillType : String): Observable&lt;Drill&gt; {
          return remoteDataSource.loadDrillList(drillType)
      }
  }
  </code></pre>
  
  <p>What I tried: </p>
  
  <ol>
  <li><p>Removing the coroutines from the mix. I thought that removing "viewmodelscope.launch" would make the test work as I thought it had something to do with coroutines and them not finishing or something in time or not listening on the proper thread.</p></li>
  <li><p>Tried using the 2 extended classes posted below(to replace the Instant Execution Rule in JUnit4)</p></li>
  <li><p>Googling a lot to find similar issues...</p></li>
  </ol>
  
  <p>Sorry for the long post, any more info or code that you need feel free to ask.If possible also point out some mistakes/ things that could be done better. Any answer with explanation is much appreciated. I really want to understand what is the underlying issue. Thank you very much! </p>
  
  <p>edit: I am considering it might be something due to RXKotlin</p>