viewmodel 中的单元测试状态流 - stateflow 只有初始值,后面分配的值不会在单元测试中返回

Ren*_*K N 5 android unit-testing kotlin-coroutines kotlin-flow

我的视图模型中有两个状态流

private val _peopleList = MutableStateFlow(emptyList<People>())
val peopleList: StateFlow<List<People>> = _peopleList

val _peopleListLoader = MutableStateFlow(false)
val peopleListLoader: StateFlow<Boolean> = _peopleListLoader
Run Code Online (Sandbox Code Playgroud)

peopleList 用于显示列表,peopleListLoader 用于在 UI 中显示进度指示器。所有这些都按预期在应用程序中正常工作。但是在我的单元测试中,当我检查peopleListLoader使用peopleListLoader.toList(values)功能时,它没有我在人员列表加载期间分配给它的值。

以下是我的实现

人员列表视图模型

@HiltViewModel
class PeopleListViewModel @Inject constructor(
    val repository: PeopleRepository,
    @MainDispatcher private val dispatcher: CoroutineDispatcher
) : ViewModel() {


    private val _peopleList = MutableStateFlow(emptyList<People>())
    val peopleList: StateFlow<List<People>> = _peopleList


    val _peopleListLoader = MutableStateFlow(false)
    val peopleListLoader: StateFlow<Boolean> = _peopleListLoader

    private val _peopleListErrorMessage = MutableStateFlow("")
    var peopleListErrorMessage: StateFlow<String> = _peopleListErrorMessage

        
    fun loadPeoplesList() {

        viewModelScope.launch(dispatcher) {

            _peopleListLoader.value = true // set the loader visibility true 
            repository.getPeopleList().collect() {
                try {
                    when {
                        it.isSuccess -> {
                            _peopleList.value = it.getOrNull()!!
                            _peopleListErrorMessage.value = ""
                        }
                        it.isFailure -> {
                            _peopleListErrorMessage.value = it.exceptionOrNull().toString()
                        }
                    }
                }finally {
                    _peopleListLoader.value = false // set the loader visibility false
                }
                
            }
        }
    }
 }
Run Code Online (Sandbox Code Playgroud)

单元测试

class PeopleListViewModelShould {


    @get:Rule
    val instantTaskExecutorRule = InstantTaskExecutorRule()

    //SUT - PeopleListViewModel

    val repository: PeopleRepository = mock()
    val peoplesList = mock<List<People>>()
    val expected = Result.success(peoplesList)



    @Test
    fun turnLoaderVisibilityFalseAfterFetchingPeoplesList()= runTest{
        
        whenever(repository.getPeopleList() ).thenReturn(
            flow {
                emit(expected)
            }
        )
        
        val testDispatcher: TestDispatcher = UnconfinedTestDispatcher()        
        val viewmodel = PeopleListViewModel(repository,testDispatcher)
        val values = mutableListOf<Boolean>()        

         val collectJob=    launch(testDispatcher){                
               
                viewmodel.peopleListLoader.toList(values)
            }
        viewmodel.loadPeoplesList()    
        System.out.println("Result is  : "+values.toString()) //This prints ony [false] iam expecting [false,true,false]       
       
        assertEquals(true, values[0]) // Assert on the list contents
        collectJob.cancel()       
    }
}
Run Code Online (Sandbox Code Playgroud)

我的单元测试出了什么问题,我感谢所有建议并提前感谢所有人..