user10557996
user10557996

Reputation:

Coroutines test with firebase hanging forever

I have made a simple unit test which tests a coroutines function which uses firebase. I've mocked all the dependencies and the methods being used in this function I'm testing, but it continues to hang. I'm not sure exactly where it's hanging, but I would assume on the mocking of firestore, and it has await().

Test Class:


import android.content.Context
import com.example.socialtoker.data.db.UserDao
import com.example.socialtoker.data.repository.UserDataRepository
import com.example.socialtoker.data.repository.UserDataRepositoryImpl
import com.google.firebase.auth.FirebaseAuth
import com.google.firebase.database.DatabaseReference
import com.google.firebase.firestore.FirebaseFirestore
import com.google.firebase.storage.FirebaseStorage
import io.mockk.*
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.runBlocking
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4

@RunWith(JUnit4::class)
@ExperimentalCoroutinesApi
class UserDataRepositoryImplTest {

    private val contextMock = mockk<Context>{
        every { getExternalFilesDir(any())?.absolutePath } returns "src/SocialToker/"
    }
    private val firestoreMock = mockk<FirebaseFirestore>{
        coEvery { collection("Users").document(any()).set(any()).await() } returns mockk()
    }
    private val firebaseAuthMock = mockk<FirebaseAuth>{
        coEvery { createUserWithEmailAndPassword(any(), any()) } returns mockk()
        every { currentUser?.uid } returns "UID"
    }
    private val firebaseStorageMock = mockk<FirebaseStorage>()
    private val firebaseDatabaseMock = mockk<DatabaseReference>()
    private val daoMock = mockk<UserDao>{
        coEvery { addUser(any()) } returns mockk()
    }

    private lateinit var userDateRepository: UserDataRepository

    private val emailAddress = "[email protected]"
    private val password = "socialtokerpassword"
    private val username = "socialtoker"



    @Before
    fun setup() {
        userDateRepository = UserDataRepositoryImpl(
            contextMock,
            firestoreMock,
            firebaseAuthMock,
            firebaseStorageMock,
            firebaseDatabaseMock,
            daoMock
        )
    }

    @Test
    fun `createUser calls firebase and stores user info locally and remotely`() = runBlocking {
        // WHEN
        userDateRepository.createUser(emailAddress, password, username)

        //THEN
        coVerify { firebaseAuthMock.createUserWithEmailAndPassword(emailAddress, password) }
    }


}

Test Subject:

    override suspend fun createUser(email: String, password: String, username: String): AuthResult {
        try {
            val data = hashMapOf(
                "name" to username
            )
            val authResult = firebaseAuth.createUserWithEmailAndPassword(email, password).await()
            val uid = firebaseAuth.currentUser!!.uid
            userDao.addUser(UserData(uid, username, "", ""))
            firestoreRef.collection("Users")
                .document(uid)
                .set(data).await()
            return authResult
        } catch (error: Throwable) {
            throw RepositoryError(
                error.localizedMessage ?: "Unable to create user", error
            )
        }
    }

Upvotes: 0

Views: 326

Answers (1)

PGliw
PGliw

Reputation: 451

Please note that await is an extension function on Task class. Therefore Mocking extension functions might need to be taken into consideration.

Upvotes: 0

Related Questions