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

标签 unit-testing android-livedata android-viewmodel kotlin-flow android-unit-testing

我需要一些关于在 android 中编写单元测试的帮助,这些测试与 View 模型、实时数据和流机制以及调度有关。
首先,我在写单元测试 ,而不是仪器测试。
实际上,我正在为一个 android 应用程序创建一个单元测试,用于测试一个使用存储库从互联网获取一些数据的 ViewModel。
我使用的 View 模型的代码是这样的:

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 函数,毕竟,然后观察我可以在哪里断言单元测试的结果。
任何帮助都会很棒。 :)
我在 app 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)

关于unit-testing - 当使用返回流的存储库对 View 模型进行单元测试时,将其转换为实时数据时会发生错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64093240/

相关文章:

Android:带有协程的易碎 ViewModel 单元测试

java - 使用 Maven 2 和 Glassfish 3 对 EJB 进行单元测试

php - 尝试使用 VFSStream 测试文件系统操作

Python:对多个文件运行相同的 Unittest 模块测试

android - 我应该将 viewModelScope.coroutineContext 传递给 liveData 构建器函数吗?

android - 无法创建 View 模型的实例

android - Dagger Hilt 'Assisted' 和 'ViewModelInject' 已弃用。在 Dagger Hilt View Model 1.0.0-alpha03

java - 在 Storm TrackedTopology 单元测试中运行 Trident 拓扑

安卓机房 : How to combine data from multiple SQL queries into one ViewModel

android - 将 ArrayAdapter 与 LiveData 结合使用。