接下来的测试将会需要用到 mocking 的 library ,在 Android 大家比较常用的是 MockK 和 Mockito 。这篇要介绍的是 MockK,它是一个专门支援 Kotlin 的 mocking library ,来看看它有哪些特点吧!
如果没有写测试经验的朋友应该不太了解甚麽是 mocking ,我们可以用一个例子来了解一下。假如我们有个 ApiService
,它对外提供 User
实体给其他人,而 ApiService
又实作了 Service
这个介面。
data class User(val name: String, val id: Long)
interface Service {
fun getUser(): User
}
class ApiService : Service {
override fun getUser() = User("John", 1L)
}
有另一个类别 UserRepository
用到了 Service
介面来提供 User
。
class UserRepository(private val service: Service) {
fun getUser(): Flow<User> = flow {
if (user.id == -1) {
throw new InvalidUserIdException()
} else {
emit(service.getUser())
}
}
}
这时候,我们要针对 UserRepository
来写测试的话,首先第一个要做的事情就是控制外部来的变数,也就是 Service
,因为他会控制我们 User 实体。如果我想要 UserRepository
丢出 InvalidUserIdException
错误的话,我可以透过一个假的 service
发出一个 id
为 -1 的假 User
来测试程序是不是会判断 id
为 -1 。相反地,我们也可以测试正向的流程,也就是 id
不为 -1 的流程,这个就是 mocking 可以做的事情。
以上面这个例子如果使用 MockK 可以怎麽测?
@Test
fun `Test getting an user info by MockK`() = runBlocking {
val fakeUser = User("Doe", 2L)
val mockApiService = mockk<ApiService>(relaxed = true)
every { mockApiService.getUser() } returns fakeUser
val userRepository = UserRepository(mockApiService)
userRepository.getUser().collect {
assertEquals(it, fakeUser)
}
}
做一个 fakeUser
放到假的 ApiService
里面,在 MockK 要做一个假的物件只要用 mockk<ApiService>
就可以了!下一行的 every...return
表示法就是指定当每次 mockApiService.getUser()
被呼叫的时候要回甚麽指定物件给呼叫的人,这边我们指定 fakeUser
。另外,你可能也有发现 mockk<ApiService>
後面有个 relaxed = true
的参数,这个主要的是让 mocking 的物件内的东西被呼叫的时候,有回给他一个基本值或是不作用,这个的好处是,假设今天我们的 ApiService
有 10 个方法,但我们只要操控 getUser
的结果,另外 9 个不管,我们只要对 getUser
做 every...return
塞值,另外 9 个不用一个个塞值。
另一个测试路线就是测试当 id 是 -1 的时候会不会丢 exception ,可以在测试方法前面写上 @Test(expected = InvalidUserIdException::class)
,意思就是说我们期待这边会丢出 InvalidUserIdException
。
@Test(expected = InvalidUserIdException::class)
fun `Test getting an user info by MockK`() = runBlocking {
val fakeUser = User("Doe", -1L)
val mockApiService = mockk<ApiService>(relaxed = true)
every { mockApiService.getUser() } returns fakeUser
val userRepository = UserRepository(mockApiService)
userRepository.getUser().collect()
}
MockK 在测试 Kotlin 程序码的时候真的很好用,因为他的 API 是支援 Kotlin 的写法,而且还有类似 DSL 的表达方式,让我们在写测试的时候可以很轻松地完成要写的测试。如果你对於 MockK 有兴趣的话,可以参考一下官网文件,他们的文件也是简单易懂,让测试可以简单就上手。
<<: Day14 NiFi - NiFi Expression Language
>>: Day 16 AWS云端实作起手式第六弹 串接两大网路流量导流服务Route53和ELB
正文 今天要设定gitlab上的专案,让他们能够在git commit时自动打包成docker im...
1.前言 今天要讲解如标题一样,Google Sheet是Google所开发的试算表,所以我们要用G...
先前介绍Azure DevOps的Pipelines的时候有提到过Azure DevOps Agen...
上篇说明了 GUI 设计里包含的二个项目:Mockup,以及 Style Guideline。这篇我...
本篇大纲:开放资料下载、绘制长条图 今天的一天一图表,我们来画图表世界中最常见的 长条图 吧!长条...