這次,需求單位又提出了一個新的想法:
我們可不可以設計一個 API,允許用戶在 2021/12/31 23:59:59 之前才能參加該活動。之後的用戶都不允許參加活動呢?
參與活動的邏輯很簡單,只是新增資料而已。這段我們不擔心。不過針對時間的限制,該怎麼在自動測試裡面進行控制呢?
今天我們就來聊聊這個部分!
首先,我們先來撰寫驗證時間的邏輯 isValidDate()
,如果現在時間還沒到 2021/12/31 23:59:59 回傳 true
,其餘時間回傳 false
這邊我們利用 java.time.*
套件
import java.time.*
fun isValidDate(): Boolean {
val clock = Clock.fixed(Instant.now(), ZoneId.of("UTC"))
val now = LocalDateTime.now(clock)
val dueDate = LocalDateTime.parse("2021-12-31T23:59:59")
return dueDate.isAfter(now)
}
邏輯撰寫好了之後,我們先簡單的測試一下
建立一個 IsValidDateKtTest.kt
並撰寫以下邏輯
import org.junit.Test
internal class IsValidDateKtTest {
@Test
fun `確認isValidDate`() {
println(isValidDate())
}
}
運行過後,我們可以看到確實印出 true
。
可是我們並不知道在其他的時間裡,特別是超過
這邊,我們要介紹一個協助我們建立 test double 的框架:mockk!
簡單說,mockk 是一個測試時協助我們在測試時,建立 test double 的框架。
引用的方式一樣透過 gradle,相信各位都很熟悉了
testImplementation("io.mockk:mockk:1.12.0")
引入之後,我們就可以利用 mockk 框架來協助我們假造 LocalDateTime.now()
我們想測試的案例是 在2022/01/01時應該回傳false
在程式裡面,我們取得現在時間的邏輯是
val clock = Clock.fixed(Instant.now(), ZoneId.of("UTC"))
val now = LocalDateTime.now(clock)
我們透過把 clock
寫死
來控制測試執行的時間是 2022-01-01T23:59:59
fun `確認isValidDate`() {
val fixedClock = Clock.fixed(
Instant.parse("2022-01-01T23:59:59Z"),
ZoneId.of("UTC")
)
mockkStatic(Clock::class)
every { Clock.systemUTC() } returns fixedClock
}
我們如果先將 isValidDate()
改寫,看看實際取得的 now()
內容
val clock = Clock.fixed(Instant.now(), ZoneId.of("UTC"))
val now = LocalDateTime.now(clock)
val dueDate = LocalDateTime.parse("2021-12-31T23:59:59")
println(now)
會印出
2022-01-01T23:59:59
這代表,透過假造我們的 Clock
物件,我們可以在測試程式裡面控制我們的時間了!
現在我們可以將 在2022-01-01時應該回傳false()
寫完
@Test
fun `在2022-01-01時應該回傳false`() {
val fixedClock = Clock.fixed(
Instant.parse("2022-01-01T23:59:59Z"),
ZoneId.of("UTC")
)
mockkStatic(Clock::class)
every { Clock.systemUTC() } returns fixedClock
Assert.assertThat(isValidDate(), `is`(false))
}
執行並確認通過之後,我們可以趁機再加上 在2021-12-30時應該回傳true
@Test
fun `在2021-12-30時應該回傳true`() {
val fixedClock = Clock.fixed(
Instant.parse("2021-12-30T23:59:59Z"),
ZoneId.of("UTC")
)
mockkStatic(Clock::class)
every { Clock.systemUTC() } returns fixedClock
Assert.assertThat(isValidDate(), `is`(true))
}
這樣,我們的 isValidDate()
功能和測試就寫完了!