Я работаю с проектом Android, который должен инициализировать токен Firebase. В основном работая с сопрограммами Kotlin, я хотел бы реализовывать код построчно, но, поскольку нет возможности синхронно запрашивать токен Firebase, я предложил решение для переноса OnCompleteListener
, используя следующую функцию:
private suspend fun fcmCallbackSuspendWrapper(block: (OnCompleteListener<InstanceIdResult>) -> Unit)
= suspendCancellableCoroutine<Task<InstanceIdResult>> { cont ->
block(OnCompleteListener { response ->
cont.resume(response)
})
}
Он в основном блокирует текущий поток до тех пор, пока Task не вызовет обратный вызов. Затем я применяю указанную функцию в своем коде следующим образом:
val fcmInstance = fcmCallbackSuspendWrapper { listener ->
fireBaseInstanceIdProvider
.provide() // Returns Firebase instance
.instanceId // Returns Task<InstanceIdResult>
.addOnCompleteListener(listener) // Sets listener to block current thread until completed
}
Но теперь мне нужно добавить модульный тест в приведенный выше код, и здесь я сталкиваюсь с несколькими проблемами:
@Mock lateinit var instanceIdResultTaskMock: Task<InstanceIdResult>
@Mock lateinit var fireBaseInstanceIdProviderMock: Provider<FirebaseInstanceId>
@Mock lateinit var firebaseInstanceIdMock: FirebaseInstanceId
...
Mockito.`when`(fireBaseInstanceIdProviderMock.provide()).thenReturn(firebaseInstanceIdMock)
Mockito.`when`(firebaseInstanceIdMock.instanceId).thenReturn(instanceIdResultTaskMock)
Но так как Task<InstanceIdResult>
является поддельным - он OnCompleteListener<TResult>
никогда не вызывается и поток блокируется навсегда, сохраняя выполнение кода для продолжения. Что можно сделать в этой ситуации?