Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

202
Views
Mock Android Firebase Task within Kotlin coroutine

I am working with Android project that needs to initialises Firebase token. Mostly working with Kotlin coroutines I would like to implement code line by line, but since there is no way to synchronously request Firebase token I came up with the solution to wrap OnCompleteListener using following function:

private suspend fun fcmCallbackSuspendWrapper(block: (OnCompleteListener<InstanceIdResult>) -> Unit)
        = suspendCancellableCoroutine<Task<InstanceIdResult>> { cont ->
    block(OnCompleteListener { response ->
        cont.resume(response)
    })
}

It basically blocks current thread until callback is called by Task. Then I'm applying said function in my code in following way:

val fcmInstance = fcmCallbackSuspendWrapper { listener ->
    fireBaseInstanceIdProvider
        .provide() // Returns Firebase instance 
        .instanceId // Returns Task<InstanceIdResult>
        .addOnCompleteListener(listener) // Sets listener to block current thread until completed
}

But now I need to add unit test to the code above and here I encounter several problems:

@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)

But since Task<InstanceIdResult> is mocked - it's OnCompleteListener<TResult> is never called and thread is blocked forever, preserving code execution to continue. What can be done in this situation?

over 4 years ago · Santiago Trujillo
2 answers
Answer question

0

I have done it by using Mockk.io, this is my code snippet, with mockito I think you may do the same thing

val mockedResult = mockk<InstanceIdResult>()
every { mockedResult.token } returns "token"

val mockedInstanceId = mockk<Task<InstanceIdResult>>()
every { mockedInstanceId.isSuccessful } returns true
every { mockedInstanceId.result } returns mockedResult

val slot = slot<OnCompleteListener<InstanceIdResult>>()
every { mockedInstanceId.addOnCompleteListener(capture(slot)) } answers {
    slot.captured.onComplete(mockedInstanceId)
    mockedInstanceId
}

every { firebaseInstanceId.instanceId } returns mockedInstanceId
over 4 years ago · Santiago Trujillo Report

0

Thanks @mcatta your snippet helped me :)

However since FirebaseIntanceId is deprecated, this is the new way to do it :

mockkStatic("com.google.firebase.messaging.FirebaseMessaging")
       
val firebaseMessagingMock = mockk<FirebaseMessaging>()
every { getInstance() } returns firebaseMessagingMock

val mockGetTokenTask = mockk<Task<String>>()
every { firebaseMessagingMock.token} returns mockGetTokenTask

val slot = slot<OnCompleteListener<String>>()
every { mockGetTokenTask.addOnCompleteListener(capture(slot)) } answers {
  slot.captured.onComplete(mockGetTokenTask)
  mockGetTokenTask
}

every {mockGetTokenTask.exception} returns null
every {mockGetTokenTask.result} returns currentToken
over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!