Android 如何对返回livedata的函数进行单元测试

Android 如何对返回livedata的函数进行单元测试,android,unit-testing,android-livedata,kotlin-coroutines,android-viewmodel,Android,Unit Testing,Android Livedata,Kotlin Coroutines,Android Viewmodel,在我的viewModel中,我有一个返回liveData的函数。该函数在片段中直接调用,因此直接在片段中观察到。我不知道如何测试这个函数,因为在测试的情况下,函数发出的liveData没有被观察到,因此它不会返回值 这是我的函数,我想为以下内容编写测试: fun saveRating(rating: Float, eventName: String): LiveData<Response<SaveRatingData?>?> { val reque

在我的viewModel中,我有一个返回liveData的函数。该函数在片段中直接调用,因此直接在片段中观察到。我不知道如何测试这个函数,因为在测试的情况下,函数发出的liveData没有被观察到,因此它不会返回值

这是我的函数,我想为以下内容编写测试:

    fun saveRating(rating: Float, eventName: String): LiveData<Response<SaveRatingData?>?> {
        val request = RatingRequest(rating.toDouble(), eventName, false)

        return liveData(viewModelScope.coroutineContext + Dispatchers.IO) {
            emit(repository.saveRatings(request))
        }

    }

提前谢谢

您需要有testCoroutineDispatcher或testCoroutineScope才能将viewModel的范围设置为测试范围

class TestCoroutineRule : TestRule {

    private val testCoroutineDispatcher = TestCoroutineDispatcher()

    val testCoroutineScope = TestCoroutineScope(testCoroutineDispatcher)

    override fun apply(base: Statement, description: Description?) = object : Statement() {

        @Throws(Throwable::class)
        override fun evaluate() {

            Dispatchers.setMain(testCoroutineDispatcher)

            base.evaluate()

            Dispatchers.resetMain()
            try {
                testCoroutineScope.cleanupTestCoroutines()
            } catch (exception: Exception) {
                exception.printStackTrace()
            }
        }
    }

    fun runBlockingTest(block: suspend TestCoroutineScope.() -> Unit) =
        testCoroutineScope.runBlockingTest { block() }

}
任何官方kotlin或Android文档中都没有提到Try-catch块,但是测试异常会导致异常,而不是像我在本文中所问的那样通过测试

我在testCoroutineDispatcher中经历的另一件事是,调度程序不足以让某些测试通过,您需要将coroutineScope而不是调度程序注入viewModel

比如说

fun throwExceptionInAScope(coroutineContext: CoroutineContext) {


    viewModelScope.launch(coroutineContext) {

        delay(2000)
        throw RuntimeException("Exception Occurred")
    }
}
您有一个这样的函数,它抛出异常,并将testCoroutineContext传递给该测试,但该测试失败

@Test(预期=运行时异常::类)
fun`引发异常的测试函数`()=
testCoroutineDispatcher.runBlockingTest{

//谢谢@Thracian!这很有帮助,但我也不得不添加instantTaskExecutorRule。没有它,liveData上会出现NullPointerException。不客气,我也写过上面的LiveDataTestUtils,但它没有设置为显示为代码,因此您可能会错过它。我现在将它改为代码。
fun throwExceptionInAScope(coroutineContext: CoroutineContext) {


    viewModelScope.launch(coroutineContext) {

        delay(2000)
        throw RuntimeException("Exception Occurred")
    }
}