Jetpack Room 测试(中篇)

188 阅读3分钟

这是我参与11月更文挑战的第6天,活动详情查看:2021最后一次更文挑战

小试牛刀

经过漫长的准备,我们终于可以开始了!还记得TDD(测试驱动开发)吗?先写测试,后写实现。所以我们先在「RoomTest.kt」文件中添加测试插入歌曲的测试案例。

@Test
    fun testInsertSongs() {
        val songs = List<Song>(10) {
            Song( songName = "夜曲", singer = "周杰伦")
        }
        dao.addSongs(songs)
        assertEquals(10, dao.findSongCount())
    }

我们先实例化一个包含10个Song对象的列表,然后用我们将要写的增加数据的函数,将10个歌曲数据加入表中,之后我们需要验证新增数据的函数的有效性,就以查看表长度是否符合预期为判定条件。

我们还需要在「TestDao.kt」中声明一下addSongs和findSongCount。

@Insert
fun addSongs(list: List<Song>)
@Query("SELECT COUNT(*) FROM Song")
fun findSongCount(): Int

那现在执行一下测试看看结果吧,应该通过的。

Room注释

你可能会觉得这有些奇怪,为什么只需要在「TestDao」接口的声明的抽象方法就能实现功能了呢?

实际上,像 @Insert(增加注释)、@Query(查询注释)这些注释是Room提供的,而使用这些注释的抽象方法后Room会帮你生成一个实现。

数据库的增删改查,Room都对应的注释:

  • @Insert 增
  • @Delete 删
  • @Update 改
  • @Query 查 此外还有个原子性注释:@Transaction

增删改的注释使用方法几乎一致,参数是可以是单个元素、多个元素或者是一个列表。返回的可能是变更的行数或者是行数列表。不过有了测试环境,我们可以用一个很低的成本去验证api的结果。(官方的文档也可能有错误和不完备的地方,或者一些进阶的用法,例如:类型转换器或者Fts4)

按照官方文档所述,@Insert会根据不同参数类型返回变更的单个行数或者行数集合,而且这个行数是long类型的,所以我们按照返回类型准备了四个测试案例,返回值类型为:Int、List<Int>、Long、List<Long>。我们现在测试中添加这一段。(注意,测试文件中的@Before和@After不需要动,之后也是一样,不在赘述)

    @Test
    fun testInsert1() {
        val song = Song( songName = "夜曲", singer = "周杰伦")
        assertEquals(1, dao.addSongs1(song))
    }
    @Test
    fun testInsert2() {
        val song = listOf(Song( songName = "夜曲", singer = "周杰伦"))
        assertEquals(listOf(1), dao.addSongs2(song))
    }
    @Test
    fun testInsert3() {
        val song = Song( songName = "夜曲", singer = "周杰伦")
        assertEquals(1L, dao.addSongs3(song))
    }
    @Test
    fun testInsert4() {
        val song = listOf(Song( songName = "夜曲", singer = "周杰伦"))
        assertEquals(listOf(1L), dao.addSongs4(song))
    }

加下来,我们在TestDao.kt中加入实现。

    @Insert
    fun addSongs1(song:Song):Int
    @Insert
    fun addSongs2(list: List<Song>):List<Int>
    @Insert
    fun addSongs3(song:Song):Long
    @Insert
    fun addSongs4(list: List<Song>):List<Long>

点击一下run,你发现这次测试甚至编译都没过去,AS会警告你「Not sure how to handle insert method's return type.无法处理你@Insert方法的返回值。」

Room的编译器检查覆盖面很广,这样也能让你尽早发现你代码的漏洞。好吧,那就删掉测试1和测试2以及它们的实现吧。再跑一下测试,就能看到成功的结果了。

image.png

增删改这三项大体相同,有兴趣的同学可以自己实验一下,之后的一篇我会开始不一样的@Query。