我刚开始接触Room、协程和Flow,发现了一个奇怪的问题:我预期为空的Flow实际上有一个空项。
我的设置如下,使用泛型T
表示我的实际实体。
interface TDao {
@Query("SELECT * FROM Table WHERE date=:date")
fun getT(date: String): Flow<T>
}
@Singleton
class TRepository @Inject constructor(
private val apiService: TApiService,
private val Tdao: TDao
) {
suspend fun getTFor(date: String): Flow<T> =
Tdao
.getT(date)
.map {
if (it == null) {
returnTFromDatabase()
} else {
it
}
}
现在,当数据库中没有任何日期为T的数据时,我期望它返回一个空的流,其中没有任何项目。但实际上,它有一个null元素,这不应该发生,因为T不可为空。我为此编写了以下测试:
@RunWith(AndroidJUnit4::class)
class TDatabaseTest {
private lateinit var db: TDatabase
private lateinit var underTest: TDao
@Before
fun setUp() {
val context = InstrumentationRegistry.getInstrumentation().context
db = Room.inMemoryDatabaseBuilder(context, TDatabase::class.java).build()
underTest = db.TDao()
}
@After
fun tearDown() {
db.close()
}
@Test
fun givenEmptyDatabase_thenHasNoItems() {
runBlocking {
val list = underTest.getT("1999").take(1).toList()
assertEquals(1, list.size)
}
}
}
......并且它通过了,因为再次返回了一个null
项。
我错过了什么?这里出了什么问题,因为我无法完全弄清楚。为什么在非空元素的流中会得到一个单独的null元素?
Any?
(链接)。 - Giorgos Neokleous