在测试过程中出现了一个奇怪的错误,我无法弄清。
这是我的视图模型-
class MediaViewModel constructor(repository: Repository) : ViewModel() {
private var _media : LiveData<List<Media>> = repository.loadMediaForFolder(...)
private val media = MediatorLiveData<List<Media>>()
private var _sortOptions = Pair(MediaSortType.DATE_MODIFIED, false)
init {
media.addSource(_media) {
viewModelScope.launch {
media.value = sortMedia(it)
}
}
}
fun getMediaList(): LiveData<List<Media>> {
return media
}
fun rearrangeMedia(sortType: MediaSortType, sortAsc: Boolean) {
viewModelScope.launch {
val pair = Pair(sortType, sortAsc)
if (_sortOptions != pair) {
_sortOptions = pair
_media.value?.let { media.value = sortMedia(it) }
}
}
}
private suspend fun sortMedia(mediaList: List<Media>)
: List<Media> {
return withContext(Dispatchers.Default) {
when (_sortOptions.second) {
true -> when (_sortOptions.first) {
MediaSortType.NAME -> mediaList.sortedBy { it.mediaName }
MediaSortType.SIZE -> mediaList.sortedBy { it.size }
...
}
false -> when (_sortOptions.first) {
MediaSortType.NAME -> mediaList.sortedByDescending { it.mediaName }
MediaSortType.SIZE -> mediaList.sortedByDescending { it.size }
...
}
}
}
}
}
非常简单的viewmodel,它在后台对_media
中的存储库数据进行排序,然后更新中介者livedata media
,它作为普通livedata公开给视图。
为此的测试类-
@ExperimentalCoroutinesApi
class MediaViewModelTest {
private val folderDao = Mockito.mock(FolderDao::class.java)
private lateinit var mediaViewModel: MediaViewModel
private lateinit var repository: Repository
@ExperimentalCoroutinesApi
@get:Rule
var mainCoroutineRule = MainCoroutineRule()
@get:Rule
val instantTaskExecutorRule = InstantTaskExecutorRule()
@Before
fun setupViewModel() {
val mediaList = ...
`when`(folderDao...).thenReturn(MutableLiveData(mediaList))
repository = Repository(folderDao)
mediaViewModel = MediaViewModel(repository)
}
@Test
fun getMedia_sortBySizeDesc() {
mediaViewModel.rearrangeMedia(MediaSortType.SIZE, false)
val mediaListVm = LiveDataTestUtil.getValue(mediaViewModel.getMediaList())
Truth.assertThat(mediaListVm).isInOrder { o1, o2 ->
(o2 as Media).size.compareTo((o1 as Media).size)
}
}
@Test
fun getMedia_sortByNameAsc_thenByWidthDesc_thenByDateAsc() {
mediaViewModel.rearrangeMedia(MediaSortType.NAME, true)
var mediaListVm = LiveDataTestUtil.getValue(mediaViewModel.getMediaList())
Truth.assertThat(mediaListVm).isInOrder { o1, o2 ->
(o1 as Media).mediaName.compareTo((o2 as Media).mediaName)
}
mediaViewModel.rearrangeMedia(MediaSortType.WIDTH, false)
mediaListVm = LiveDataTestUtil.getValue(mediaViewModel.getMediaList())
Truth.assertThat(mediaListVm).isInOrder { o1, o2 ->
(o2 as Media).width.compareTo((o1 as Media).width)
}
mediaViewModel.rearrangeMedia(MediaSortType.DATE_MODIFIED, true)
mediaListVm = LiveDataTestUtil.getValue(mediaViewModel.getMediaList())
Truth.assertThat(mediaListVm).isInOrder { o1, o2 ->
(o1 as Media).dateModified.compareTo((o2 as Media).dateModified)
}
}
}
LiveDataTestUtil已摘自here
我正在尝试测试我的VM是否正确地对数据进行排序,为此,我进行了两项测试-一个仅执行单个排序,另一个执行一系列排序,一个又一个。
问题是,第一个测试成功完成,但是第二个尝试第二个断言时失败,即由于某种原因,数据未能按宽度排序。但是,如果我以调试模式运行并逐步进行,则测试将成功完成。另外,我发现我可以做一个最终断言,但是中间的断言会失败。这样行得通-
mediaViewModel.rearrangeMedia(MediaSortType.NAME, true)
var media = LiveDataTestUtil.getValue(mediaViewModel.getMediaList())
mediaViewModel.rearrangeMedia(MediaSortType.WIDTH, false)
mediaViewModel.rearrangeMedia(MediaSortType.DATE_MODIFIED, true)
Truth.assertThat(media).isInOrder { o1, o2 ->
(o1 as Media).dateModified.compareTo((o2 as Media).dateModified)
}
但这不是-
mediaViewModel.rearrangeMedia(MediaSortType.NAME, true)
val media = LiveDataTestUtil.getValue(mediaViewModel.getMediaList())
Truth.assertThat(media).isInOrder { o1, o2 ->
(o1 as Media).mediaName.compareTo((o2 as Media).mediaName)
}
mediaViewModel.rearrangeMedia(MediaSortType.WIDTH, false)
Truth.assertThat(media).isInOrder { o1, o2 -> // Fails
(o2 as Media).width.compareTo((o1 as Media).width)
}
mediaViewModel.rearrangeMedia(MediaSortType.DATE_MODIFIED, true)
Truth.assertThat(media).isInOrder { o1, o2 ->
(o1 as Media).dateModified.compareTo((o2 as Media).dateModified)
}
这通过了,但有时也失败了,这意味着存在比赛条件-
mediaViewModel.rearrangeMedia(MediaSortType.NAME, true)
Truth.assertThat(getValue(mediaViewModel.getMediaList())).isInOrder { o1, o2 ->
(o1 as CachedMedia).mediaName.compareTo((o2 as CachedMedia).mediaName)
}
mediaViewModel.rearrangeMedia(MediaSortType.WIDTH, false)
mediaViewModel.rearrangeMedia(MediaSortType.DATE_MODIFIED, true)
Truth.assertThat(getValue(mediaViewModel.getMediaList())).isInOrder { o1, o2 ->
(o1 as CachedMedia).dateModified.compareTo((o2 as CachedMedia).dateModified)
}
这是怎么回事?