【问题标题】:Why Unit tests with coroutines delay() fails?为什么使用协程延迟()进行单元测试会失败?
【发布时间】:2019-08-14 14:41:13
【问题描述】:

我有这段代码我确实想测试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)
  }
}

【问题讨论】:

    标签: android kotlin kotlin-coroutines


    【解决方案1】:

    我添加了 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)
          }
        }
      }```
    

    【讨论】:

      猜你喜欢
      • 2018-04-20
      • 2012-07-03
      • 2019-04-15
      • 1970-01-01
      • 1970-01-01
      • 2020-07-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多