我是测试的新手,我想学习如何使用MVVM模式测试协程。我只关注了https://github.com/android/architecture-samples项目,并做了一些更改(删除了远程源)。但是,当测试ViewModel以从存储库中获取数据时,它会继续失败并显示此错误。
Ruby version - 2.5.3
Rails version - 5.2.3
以下是value of : iterable.size()
expected : 3
but was : 0
iterable was: []
Expected :3
Actual :0
的测试类,不知道我缺少什么。另外,在模拟存储库时,我可以在打印ViewModel
时从中获得预期的结果,它在调用taskRepository.getTasks()
LiveData
上
loadTasks()
@ExperimentalCoroutinesApi
@RunWith(MockitoJUnitRunner::class)
class TasksViewModelTest {
private lateinit var tasksViewModel: TasksViewModel
val tasksRepository = mock(TasksRepository::class.java)
@ExperimentalCoroutinesApi
@get:Rule
var mainCoroutineRule = TestMainCoroutineRule()
// Executes each task synchronously using Architecture Components.
@get:Rule
var instantExecutorRule = InstantTaskExecutorRule()
@Before
fun setupViewModel() {
tasksViewModel = TasksViewModel(tasksRepository)
}
@Test
fun whenLoading_hasListOfTasks() = runBlockingTest {
val task1 = Task("title1", "description1")
val task2 = Task("title2", "description2")
val task3 = Task("title3", "description3")
`when`(tasksRepository.getTasks()).thenReturn(Result.Success(listOf(
task1,
task2,
task3
)))
tasksViewModel.loadTasks()
val tasks = LiveDataTestUtil.getValue(tasksViewModel.tasks)
assertThat(tasks).hasSize(3)
}
}
下面列出了Helper类,我只是从示例项目中复制了相同的类。
class TasksViewModel @Inject constructor(
private val repository: TasksRepository
) : ViewModel() {
private val _tasks = MutableLiveData<List<Task>>().apply { value = emptyList() }
val tasks: LiveData<List<Task>> = _tasks
fun loadTasks() {
viewModelScope.launch {
val tasksResult = repository.getTasks()
if (tasksResult is Success) {
val tasks = tasksResult.data
_tasks.value = ArrayList(tasks)
}
}
}
}
object LiveDataTestUtil {
/**
* Get the value from a LiveData object. We're waiting for LiveData to emit, for 2 seconds.
* Once we got a notification via onChanged, we stop observing.
*/
fun <T> getValue(liveData: LiveData<T>): T {
val data = arrayOfNulls<Any>(1)
val latch = CountDownLatch(1)
val observer = object : Observer<T> {
override fun onChanged(o: T?) {
data[0] = o
latch.countDown()
liveData.removeObserver(this)
}
}
liveData.observeForever(observer)
latch.await(2, TimeUnit.SECONDS)
@Suppress("UNCHECKED_CAST")
return data[0] as T
}
}
答案 0 :(得分:0)
事实证明,这是mockito的问题,我有一个较旧的版本,并且发现有一个名为mockito-kotlin
的库可以简化here所述的协程测试。然后,我将代码修改为此,并且运行良好。
tasksRepository.stub {
onBlocking { getTasks() }.doReturn(Result.Success(listOf(task1, task2, task3)))
}