单元测试在 Firebase 任务的 addOnCompleteListener 之后停止 API

Unit test stops after addOnCompleteListener of the Firebase Task API

我已经为我的应用程序实现了我的第一个测试用例。在每个测试用例之前,我需要使用 Firebase 登录。

我已经使用任务 API 在我的 Firebase class 中编写了所有程序。 Firebase class 是异步的,但是会发回一个 Task,可以使用 addOnCompleteListener 读取结果。但是,在登录后,logUserIn() 测试停止并且 "someNumber" 没有得到打印。我不能将 logUserIn() 方法放在 @Before 方法中,因为它是异步的。

@RunWith(AndroidJUnit4::class)
class NetworthServiceTest {

    @Rule
    @JvmField
    val rule = ActivityTestRule(MainActivity::class.java)

    private fun logUserIn(): Task<Boolean> {
        val tcs = TaskCompletionSource<Boolean>()

        val task = FirebaseService().initialize(
                TEST_USER_EMAIL,
                TEST_USER_PASSWORD,
                rule.activity)

        task.addOnCompleteListener {
            Assert.assertEquals("User " + TEST_USER_EMAIL + " cannot be logged in", "", it.result.second)

            val loginManager = UtilsProvider().getBookyLoginManager()
            Assert.assertEquals("User should be logged in", true, loginManager.isLoggedIn())

            tcs.setResult(true)
        }

        return tcs.task
    }

    @Test
    @Throws(Exception::class)
    fun whenReadingTableShouldGive10Results() {
        val task = logUserIn()
        task.addOnCompleteListener {
            val someNumber = 10
            Log.d("","print nr = "+ someNumber)
        }
    }
}


class FirebaseService {

    fun initialize(email: String, password: String, activity: Activity): Task<Pair<Any, String>> {
        database = FirebaseDatabase.getInstance().reference
        auth = FirebaseAuth.getInstance()

        val tcs = TaskCompletionSource<Pair<Any, String>>()

        auth!!.signInWithEmailAndPassword(email, password)
                .addOnCompleteListener(activity) { task ->
                    if (task.isSuccessful) {
                        user = auth!!.currentUser
                        isInitialized = true
                        val pair = Pair<Any, String>(null, "")
                        tcs.setResult(pair)
                    } else {
                        val pair = Pair<Any, String>(null, "error: " + task.exception!!.message)
                        tcs.setResult(pair)
                    }
                }
        return tcs.task
    }
}

您可以 use Tasks.await() to block the current thread to wait for the completion of a task. This is very much not recommended for application code (read more about that in this blog),但应该可以进行测试。