Day 27:DB也是假的 建立Mock SQLDelight

Keyword: SQLDelight Mock Test
直到27日,完成KMM的测试功能放在
KMMDay27


昨天测试了Ktor,今天开始也要测试SQLDelight的运作正不正常.SQLDelight的测试非常简单,只要利用SQLDriver建立一个Mock的SQLDelight Database即可.其他就跟一般使用是相同流程.跟证实环境同样的,要因应不同平台撰写SqlDriver

建立SQLDelight DB Driver

我们先在昨天的commonTest资料夹下,mockKtor的相同层级,建立一个expect fun 来提供SqlDriver

//这是在commonTest底下的任意档案 使用Kotlin语言
internal expect fun testDbConnection(): SqlDriver

然後有expect就有actual ,在双平台实作actual方法.同样的actual的package page要与expect相同.

首先是Android,我们直接照着CafeDB的Schema建立AndroidSqliteDriver

//这是在androidTest底下的实作testDBConnection 使用Kotlin语言

internal actual fun testDbConnection(): SqlDriver {
    val app = ApplicationProvider.getApplicationContext<Application>()
    return AndroidSqliteDriver(CafeDB.Schema, app, "cafedb")
}

然後iOS的部分也类似的做,同样建立NativeSqliteDriver.因为iOS与Android所使用到的Driver种类是不同的.

//这是在iosTest底下的实作testDBConnection 使用Kotlin
actual fun testDbConnection(): SqlDriver {
    val schema = CafeDB.Schema
    return NativeSqliteDriver(
        DatabaseConfiguration(
            name = "cafeDB",
            version = schema.version,
            create = { connection ->
                wrapConnection(connection) { schema.create(it) }
            },
            upgrade = { connection, oldVersion, newVersion ->
                wrapConnection(connection) { schema.migrate(it, oldVersion, newVersion) }
            },
            inMemory = true
        )
    )
}

有了Driver就有如有了DB,我们开始撰写测试

DB Test

回到commonTest的package底下,我们开始撰写有关DB测试的测试案例.虽然可以直接写在昨天的测试案例档内,但是由於要测试的部分不同,还是开一个新的测试档SQLDelightTest吧

//这是在commonTest底下的测试档 使用Kotlin
class SQLDelightTest : BaseTest() {

    private lateinit var dbHelper: DatabaseHelper

    @BeforeTest
    fun setup() = runTest {//在开始测试前会执行这段 建立新的dbHelper
        dbHelper = DatabaseHelper(
            testDbConnection(),//这段会使用到SQLDriver,由各平台实作
            Dispatchers.Default
        )
      
    }
}

然後我们在开始测试之前先偷塞几笔假资料进去

//这是在commonTest底下的测试档 使用Kotlin
class SQLDelightTest : BaseTest() {

    private lateinit var dbHelper: DatabaseHelper

    @BeforeTest
    fun setup() = runTest {
        dbHelper = DatabaseHelper(
            testDbConnection(),
            Dispatchers.Default
        )
        dbHelper.deleteALLCafe()//清空测试DB
        dbHelper.insertFakeCafe(0)//偷塞假资料
    }

		private suspend fun DatabaseHelper.insertFakeCafe(id: Int) {
        val fakeList = listOf(CafeResponseItem("fakeId$id", "fakeAddress", "fakeName", "fakeCity"))
        insertCafeList(fakeList)
    }
}

然後撰写测试内容,来测试Query的回传值正不正确

class SQLDelightTest : BaseTest() {
		...
		@Test
    fun queryTest() = runTest {
        val CAFEList = dbHelper.selectAllItems().first()
        assertNotNull(CAFEList.find { it.id == "fakeId0" }, "cant find target CAFE")
    }
		...
}

以及DeleteAll有没有正常运作

class SQLDelightTest : BaseTest() {
		...
		@Test
    fun DeleteAllTest() = runTest {
        dbHelper.insertFakeCafe(1)
        dbHelper.insertFakeCafe(2)
        assertTrue(dbHelper.selectAllItems().first().isNotEmpty())
        dbHelper.deleteALLCafe()

        assertTrue(
            dbHelper.selectAllItems().first().count() == 0,
            "delete all Cafe not complete"
        )
    }
}

执行看看结果

https://github.com/officeyuli/itHome2021/raw/main/day27/1633187669816.jpg


<<:  Day17 NodeJS-Express II

>>:  演讲该让人打包带走的东西

Day23【Web】网路通讯协定 TCP/IP

什麽是 TCP/IP? 早期网路刚开始萌芽时, 由於不同公司的硬体产品开发的网路技术, 彼此的连网技...

Day25:终於要进去新手村了-Javascript-函式-物件综合范例

今天我们举例的范例依然是由彭彭影片内的范例程序码加上自己所能理解的方式做个纪录以及学习。 在影片之中...

【Day 1】大纲 / 30 天的学习计画

身为一个普大的普通大学生, 实战经验少得可怜, 除了学过资工基本学科,就只会用 Python 写 L...

12. STM32-CANBus概念介绍

CAN Protocol 介绍 CAN 全名为控制器区域网路 (Controller Area Ne...

Day 9 - [Zenbo开发系列] 06-安装DDE语料到Zenbo

今天使用的范例出自高焕堂老师的书《AI机器人、蓝芽与Android整合开发技术》,需要完整程序码请参...