房间和Coroutines测试
#测试 #android #coroutines

我的last article介绍了一些简单的示例,内容涉及房间和RXJAVA仪器测试代码。 Coroutines在单元测试中也具有great support ,即使今天的主题与它无关。我的意思是,这次我们不会涵盖RunblockingTest。 Android不支持这一点(如果我错了,请纠正我)。但是,我可以安排一个话题,因为它确实使我兴奋。您也可以从Sean McQuillan检查this awesome talk,我发现这很有帮助。

与最后的GIST相比,我们将尝试从RX跳到Coroutines(无实现),并为其编写测试类。我们可以将方法标记为suspended:
而不是将方法标记为

@Dao
interface HabitDao {
    @Insert
    suspend fun insertHabit(habit: Habit) //used to return Completable

    @Query("SELECT * FROM user_habits WHERE end_date >= :todaysDate")
    suspend fun selectAllActiveHabits(todaysDate: Date): List<Habit> //used to return Flowable<List<Habit>>

    @Query("SELECT * FROM user_habits WHERE end_date < :todaysDate")
    suspend fun selectAllInactiveHabits(todaysDate: Date): List<Habit> //used to return Flowable<List<Habit>>

    @Query("DELETE FROM user_habits WHERE id = :id")
    suspend fun deleteHabit(id: Long) //used to return Completable

    @Query("UPDATE user_habits SET start_date = :startDate, end_date = :endDate , receive_notification = :notification WHERE id = :id")
    suspend fun updateWhereId(startDate: Date, endDate: Date, notification: Boolean, id: Long) //used to return Completable

    @VisibleForTesting
    @Query("SELECT * FROM user_habits")
    suspend fun selectAll(): List<Habit> //used to return Flowable<List<Habit>>
}

这看起来更容易(或者更好地说令人困惑)。

在上一篇文章中查看代码,请注意,您将不需要Instanttaskexecutorrule()和突然我们不会在主线程上运行查询。那是因为如果将方法标记为suspended,我们将无法做到这一点。

让我们开始测试:

@RunWith(AndroidJUnit4::class)
class HabitDaoTest{
    private lateinit var careFlectDatabase: CareFlectDatabase //the db instance
    private lateinit var habitDao: HabitDao //the dao

    @Before
    fun setUp() {
        val context = ApplicationProvider.getApplicationContext<Context>()
        careFlectDatabase = Room.inMemoryDatabaseBuilder(context, CareFlectDatabase::class.java)
            .build()

        habitDao = careFlectDatabase.habitDao()
    }

    @After
    fun tearDown() {
        careFlectDatabase.close()
    }
}

请注意,我们丢弃了允许的Mainthreadqueries()。

现在查询:

 @Test
    fun presentDateShouldReturnInsertion() = runBlocking {
        val today = getInstance().apply {
            set(MONTH, 10)
            set(YEAR, 2019)
            set(DAY_OF_MONTH, 1)
        }

        val yesterday = getInstance().apply {
            set(MONTH, 9)
            set(YEAR, 2019)
            set(DAY_OF_MONTH, 30)
        }

        val habit = Habit(0, "Quit Smoking", yesterday.time, today.time, true)

        habitDao.insertHabit(habit)

        val selection = habitDao.selectAll()

        assertEquals(listOf(habit), selection)
    }

太熟悉了吗?这里的关键成分只是一个runblocking的关键字,它可以确保运行您的悬挂方法。我想没有必要为更新或删除测试的部分添加代码。这只是超级当务之急,这里没有秘密可以让您失去理智(指RX-Javas BlockingaWait()),因为Coroutine确保在下面的代码之前执行插入。

不是很小的比较:

我都爱。但是我认为当我们进入Kotlin(尤其是Coroutines)上下文时,RX确实是多余的。

结论

Coroutines每天都得到Google Android团队的支持,这真的很棒。新图书馆正在Kotlin编写,Coroutines是其中的一部分。我真正喜欢测试的房间和珊瑚酸是我从来没有故意忘记在项目上测试Daos,我总是准备好编写测试(即使我还没有进行更多测试超过8个月)。

注意:如果您想进一步了解Room + Coroutines,here是Florina Muntenescu的一篇不错的文章,还涵盖了一些深入的潜水,并在幕后如何建立Coroutine支持。

Stavro Xhardha