从测试中的挂起函数调用时,我的 MutableStateFlow 不发出

My MutableStateFlow doesnt emit when called from suspend function in test

我正在尝试为我的存储库编写测试,它提供对我的房间数据库的访问。 为此,我写了一个模拟数据库和一个模拟 DAO:

我的数据库:

abstract class JoozdlogDatabase protected constructor(): RoomDatabase() {
    abstract fun aircraftTypeDao(): AircraftTypeDao
    // (...)
}
class MockDatabase: JoozdlogDatabase() {
    override fun aircraftTypeDao(): AircraftTypeDao = MockAircraftTypeDao()
}

我的 DAO:

interface AircraftTypeDao {
    @Query("SELECT * FROM AircraftTypeData")
    suspend fun requestAllAircraftTypes(): List<AircraftTypeData>

    @Query("SELECT * FROM AircraftTypeData")
    fun aircraftTypesFlow(): Flow<List<AircraftTypeData>>
    
    // etc etc //
}
class MockAircraftTypeDao: AircraftTypeDao {
    private val simulatedDatabase = ArrayList<AircraftTypeData>()
    private val simulatedFlow = MutableStateFlow<List<AircraftTypeData>>(listOf(AircraftTypeData("aap", "noot", false, multiEngine = false)))

    override suspend fun requestAllAircraftTypes(): List<AircraftTypeData> = simulatedDatabase

    override fun aircraftTypesFlow(): Flow<List<AircraftTypeData>> = simulatedFlow

    override suspend fun save(vararg aircraftTypeData: AircraftTypeData) {
        //println("${this::class.simpleName} Saving ${aircraftTypeData.size} type data")
        simulatedDatabase.addAll(aircraftTypeData)
        emit()
    }

    override suspend fun clearDb() {
        println("${this::class.simpleName} Clear DB")
        simulatedDatabase.clear()
        emit()
    }

    private fun emit(){
        println("emit() should emit ${simulatedDatabase.size} items")
        simulatedFlow.update { simulatedDatabase.toList() } // also tried: simulatedFlow.value = simulatedDatabase.toList()
        println("simulatedFlow.value is now ${simulatedFlow.value.size}")
    }

我的测试数据:

object TestData {
    val aircraftTypes = listOf(
        AircraftType("Test Aircraft 1 (MP/ME)", "TAC1", multiPilot = true, multiEngine = true),
        AircraftType("Test Aircraft 2 (SP/SE)", "TAC2", multiPilot = false, multiEngine = false)
    )
}

和我的测试:

@Test
fun test() {
    runTest {
        var currentTypesList: List<AircraftType> = emptyList()
        val aircraftRepository = AircraftRepository.mock(MockDatabase())
            // DispatcherProvider.default() provides UnconfinedTestDispatcher(TestCoroutineScheduler()) for my test.
        launch(DispatcherProvider.default()) {
            aircraftRepository.aircraftTypesFlow.collect {
                println("emitted ${it.size} flights: $it")
                currentTypesList = it
            }
        }
        aircraftRepository.replaceAllTypesWith(TestData.aircraftTypes)
        delay(500)
        println("Done waiting")
        assertEquals (2, currentTypesList.size)
    }
}

预期结果:测试通过。 收到的结果:java.lang.AssertionError: expected:<2> but was:<1> 对于单个断言

收到输出:

emitted 1 flights: [AircraftType(name=aap, shortName=noot, multiPilot=false, multiEngine=false)]
MockAircraftTypeDao Clear DB
emit() should emit 0 items
simulatedFlow.value is now 0
emit() should emit 2 items
simulatedFlow.value is now 2
Done waiting

现在,我整个上午都在做这个,我只是不明白为什么它除了第一个值什么都不收集。 我尝试过的事情:

制作流对象来测试我的收集器 -> 收集器正常

直接访问 DAO 中的流项 -> 不起作用

updatevalue = 设置 MutableStateFlow 的值 -> 都不起作用。

创建一个完全相同但不是从挂起函数调用的不同流对象:有效。

所以,我猜想调用挂起函数有什么地方做错了,但是 Flow 对象在延迟结束之前正在更新,它就是不会收集。 如果有人比我聪明得多并且可以解释我做错了什么,我将不胜感激。

我使用发布的建议 here and switching to turbine 解决了这个问题,以满足我所有的流量测试需求。