为什么带有协程的delay()单元测试失败?

时间:2019-08-14 14:41:13

标签: android kotlin kotlin-coroutines

我有这段代码我想测试loadSession()testLoadSession()是测试方法,我有SuccessActivationCodeRepository进行单元测试,observeForTesting是扩展功能 您可以看到我在单元测试中添加了更长的延迟,但是这并没有为sessionData返回null,该如何解决?

fun loadSession(activationCode: ActivationCode) {
    viewModelScope.launch {
      delay(START_DELAY)
      when (val result = activationCodeRepository.fetchSession(activationCode)) {
        is Response.Success<ISession> -> {
          sessionMutableData.postValue(result.data)
        }
        is Response.Failure -> {
          if (result.message == ERROR_RETRY_ACTIVATION) {
            retryActivationMutableData.postValue(true)
          } else {
            errorMessageMutableData.postValue(ConsumableValue(result.message))
          }
        }
      }
    }
  } 


@Test
  fun testLoadSession() {
    viewModel.activationCodeRepository = SuccessActivationCodeRepository()
    val activationCode = ActivationCode()
    val expectedSession = Session("", "", "")
    viewModel.loadSession(activationCode)
    runBlocking {
      delay(10000L)
    }
    viewModel.sessionData.observeForTesting {
     assertThat(viewModel.sessionData.value?.sessionToken).isEqualTo(expectedSession.sessionToken)
    }
  }

class SuccessActivationCodeRepository : IActivationCodeRepository {
  override suspend fun fetchSession(activationCode: ActivationCode): Response<ISession> {
    return Response.Success(Session())
  }
}

fun <T> LiveData<T>.observeForTesting(block: () -> Unit) {
  val observer = Observer<T> { Unit }
  try {
    observeForever(observer)
    block()
  } finally {
    removeObserver(observer)
  }
}

1 个答案:

答案 0 :(得分:0)

我添加了coroutinesTestRule.testDispatcher.runBlockingTest {}和advanceTimeBy(20000L)并在loadSession()中将时间设置为大于延迟时间

 @Test
  fun testLoadSession() {
    viewModel.activationCodeRepository = SuccessActivationCodeRepository()
    val activationCode = ActivationCode()
    val expectedSession = Session()
    coroutinesTestRule.testDispatcher.runBlockingTest {
      viewModel.loadSession(activationCode)
      viewModel.sessionData.observeForTesting {
        advanceTimeBy(20000L)
        assertThat(viewModel.sessionData.value.sessionToken).isEqualTo(expectedSession.sessionToken)
      }
    }
  }```