当使用返回流的存储库对视图模型进行单元测试时,将其转换为实时数据时会发生错误

问题描述

我需要一些有关在android中编写与视图模型,实时数据和流机制以及调度有关的单元测试的帮助。

首先,我编写单元测试,而不是编写测试。

实际上,我为一个Android应用创建了单元测试,用于测试使用存储库从互联网获取某些数据的viewmodel。

我使用的viewmodel的代码如下:

class viewmodel(private var repository: Repository? = Repository()) :
  androidx.lifecycle.viewmodel() {

  val data: LiveData<Result<Item>> = repository!!.remoteData.asLiveData()
}

单元测试代码如下:

import junit.framework.TestCase
import kotlinx.coroutines.dispatchers
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.test.TestCoroutinedispatcher
import kotlinx.coroutines.test.resetMain
import kotlinx.coroutines.test.runBlockingTest
import kotlinx.coroutines.test.setMain
import org.junit.After
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mockito.`when`
import org.mockito.Mockito.mock
import org.mockito.junit.MockitoJUnitRunner

@ExperimentalCoroutinesApi
@RunWith(MockitoJUnitRunner::class)
class viewmodelTest : TestCase() {
    private val testdispatcher = TestCoroutinedispatcher()
    private lateinit var repository: Repository
    private lateinit var viewmodel: viewmodel

    @Before
    public override fun setUp() {
        dispatchers.setMain(testdispatcher)
        repository = mock(Repository::class.java)
        viewmodel = viewmodel(repository)
    }

    @After
    public override fun tearDown() {
        super.tearDown()
        dispatchers.resetMain()
        testdispatcher.cleanupTestCoroutines()
    }

    @Test
    fun `remote data is returned`() = runBlockingTest {
        try {
          `when`(repository.remoteData).thenReturn(
            flowOf(Result.success(Item(SampleData.remoteData.apiResult!!)))
          )
          viewmodel.data.observeForever { result ->
                assertTrue(result.isSuccess)
            }
        } catch (exception: Exception) {
            fail()
        }
    }

}

在创建单元测试并运行它时,会发生以下错误

java.lang.IllegalArgumentException: Parameter specified as non-null is null: method androidx.lifecycle.FlowLiveDataConversions.asLiveData,parameter $this$asLiveData

至于错误,似乎我需要将参数传递给 viewmodel.data 值,但是,哪个?根据代码,它不需要参数。

我想知道模拟返回流对象的方法,因为 asLiveData()函数是在运行测试时会抛出上述异常的函数

此外,我认为我需要了解用于执行和观察实时数据值的 observeForever 函数,毕竟,这是在观察我可以断言单元测试结果的位置。

>

任何帮助都会很棒。 :)

我在应用程序build.gradle文件中使用以下库:

    testImplementation "junit:junit:4.13"
    testImplementation "com.squareup.okhttp3:mockwebserver:4.7.2"
    testImplementation "org.mockito:mockito-core:3.3.3"
    testImplementation "androidx.arch.core:core-testing:2.1.0"
    testImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-test:1.3.2"
    androidTestImplementation "androidx.test.ext:junit:1.1.2"
    androidTestImplementation "androidx.test.espresso:espresso-core:3.3.0"

解决方法

您需要先模拟 repository.remoteData,然后才能初始化 ViewModel

`when`(repository.remoteData).thenReturn(
            flowOf(Result.success(Item(SampleData.remoteData.apiResult!!)))
          )
viewModel = ViewModel(repository)