【问题标题】:How to run unit tests on Android Firebase Kotlin?如何在 Android Firebase Kotlin 上运行单元测试?
【发布时间】:2026-01-12 17:35:02
【问题描述】:

所以我正在使用 Firebase 后端构建一个聊天应用程序。在实现 ViewModel 和实际片段之前,我想检查我的 Firebase 存储库是否工作。我获取用户的电话将是这样的

Fragmet -> ViewModel -> Repository -> FirebaseRepository -> 暂停乐趣 getAllUsers() : ArrayList

代码是:

class Repository(val firebaseRepository : FirebaseRepository) {

    suspend fun getAllUsersFromFirebase() : ArrayList<UserInfo> {
        return firebaseRepository.getAllUsers()
    }

}

class FirebaseRepository() {

    private val TAG = "FIREBASE REPOSITORY : "

    private val firebaseAuth:FirebaseAuth = FirebaseAuth.getInstance()
    private val firebaseDatabase :FirebaseDatabase = FirebaseDatabase.getInstance()

    suspend fun getAllUsers() : ArrayList<UserInfo> {
        val ref = firebaseDatabase.getReference("/users")
        val userList = ArrayList<UserInfo>()

        ref.addListenerForSingleValueEvent(object : ValueEventListener{
            override fun onDataChange(snapshot: DataSnapshot) {
                if(snapshot.exists()) {
                    Log.d(TAG,"$snapshot")
                    val tempList = ArrayList<UserInfo>()
                    for(child in snapshot.children){
                        val temp = child.getValue(UserInfo::class.java)
                        if(!temp?.userId!!.equals(firebaseAuth.currentUser!!.uid)) {
                            tempList.add(temp)
                        }
                    }
                }
            }

            override fun onCancelled(error: DatabaseError) {
                Log.d(TAG,"$error ${error.message}")
            }

        })

        if(userList.isEmpty()) {
            userList.add(UserInfo("NO USER FOUND","NO USER FOUND","NO USER FOUND","NO USER FOUND"))
        }

        return userList
    }
}

那么我该如何测试呢?我推测 firebaseAuth 可能会造成问题。我想我可以处理它,但我该如何测试这个 firebase 调用?

【问题讨论】:

    标签: android firebase unit-testing kotlin firebase-realtime-database


    【解决方案1】:

    我想检查我的 firebase 存储库是否正常工作。

    它不起作用,因为您正在返回 userList 作为方法的结果,这实际上是不可能的,因为 Firebase API 是异步的。所以这里的问题是,您附加的侦听器在查询完成后的一段未知时间内被调用,您永远不知道它需要多长时间。根据您的连接速度和状态,数据可用可能需要几百毫秒到几秒钟的时间。

    话虽如此,在调用回调之前,您的 userList 将是空的。这意味着您应该始终使用回调中的结果。我已经写了一篇关于这个主题的文章,这将帮助您理解这个概念:

    如果您想创建一个单元测试,那么我建议您使用mockito 并使用以下帖子中的答案:

    附:你的 getAllUsers() 方法不需要是一个挂起的乐趣,因为你没有在那里使用任何 await() 。如果您想使用它,我建议您阅读以下文章:

    【讨论】:

    • 好的。所以我的挂起函数将返回一个空列表,因为它是异步的,并且当它获取数据时,我的函数已经返回了一个列表。我知道,只是错过了。为了解决这个问题,我想我会使用 withContext(Dispatchers.IO) { firebaseCall } 。对于测试部分,我将查看您提供的链接。谢谢@Alex。
    • 尝试阅读链接的article,并查看对应的repo
    • 谢谢@Alex。我阅读了整个 .get() 链接,发现与您使用的方法有些不同。所以我完成了函数: userRef.get().addOnSuccessListener{ // 使列表 }.await() .