我需要一些关于在 android 中编写单元测试的帮助,这些测试与 viewmodel、livedata 和流机制以及调度有关。
首先,我正在编写单元测试,而不是仪器测试。
实际上,我为 Android 应用程序创建了一个单元测试,用于测试使用存储库从互联网获取一些数据的 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()函数是在运行测试时抛出上述异常的函数。
另外,我认为我需要了解用于执行和观察来自 livedata 的值的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"