今天会为上一篇所写的两个 use case 加上 unit test。
GetLinesAndStationsUseCaseImplTest
这个 test 其实很简单,因为本身就是直接把 EtaRepository
拿到的 Map
return 出去,所以 unit test 我们只需 mock EtaRepository
的 getLinesAndStations
然後检查 use case return 出来的 map 是不是跟我们 mock 出来的 getLinesAndStations
return value 是否一致即可。
private val DUMMY_DATA = mapOf(
Line.AEL to setOf(Station.HOK, Station.KOW),
Line.TKL to setOf(Station.NOP, Station.YAT, Station.LHP),
)
class GetLinesAndStationsUseCaseImplTest {
private lateinit var useCase: GetLinesAndStationsUseCase
@MockK
private lateinit var repository: EtaRepository
@Before
fun setUp() {
MockKAnnotations.init(this)
useCase = GetLinesAndStationsUseCaseImpl(repository)
every { repository.getLinesAndStations() } returns DUMMY_DATA
}
@Test
fun invoke() {
expectThat(useCase()).isEqualTo(DUMMY_DATA)
}
}
GetEtaUseCaseImplTest
另一个 unit test 是关於车站班次,基本上都是左手交右手(把 EtaRepository
return 出来的东西直接 return 给 ViewModel 用),唯独是在 EtaResult.Success
时我们会再排序。所以我们这次测试的重点会落在 EtaResult.Success
的情景。首先是测试按行车方向排序:
class GetEtaUseCaseImplTest {
private lateinit var useCase: GetEtaUseCase
@MockK
private lateinit var repository: EtaRepository
@Before
fun setUp() {
MockKAnnotations.init(this)
useCase = GetEtaUseCaseImpl(repository)
}
@Test
fun `success, sort by direction`() = runBlockingTest {
coEvery {
repository.getEta(
Language.ENGLISH,
Line.TCL,
Station.OLY
)
} returns EtaResult.Success(
schedule = listOf(
EtaResult.Success.Eta(
direction = EtaResult.Success.Eta.Direction.DOWN,
platform = "1",
time = Instant.ofEpochSecond(1630700001),
destination = Station.HOK,
sequence = 2,
),
EtaResult.Success.Eta(
direction = EtaResult.Success.Eta.Direction.UP,
platform = "1",
time = Instant.ofEpochSecond(1630700002),
destination = Station.TSY,
sequence = 2,
),
EtaResult.Success.Eta(
direction = EtaResult.Success.Eta.Direction.UP,
platform = "1",
time = Instant.ofEpochSecond(1630700002),
destination = Station.TUC,
sequence = 1,
),
EtaResult.Success.Eta(
direction = EtaResult.Success.Eta.Direction.DOWN,
platform = "1",
time = Instant.ofEpochSecond(1630700004),
destination = Station.KOW,
sequence = 1,
),
),
)
val result =
useCase.invoke(Language.ENGLISH, Line.TCL, Station.OLY, GetEtaUseCase.SortBy.DIRECTION)
expectThat(result).isA<EtaResult.Success>().get(EtaResult.Success::schedule).hasSize(4)
.and {
get(0).get(EtaResult.Success.Eta::destination).isEqualTo(Station.TUC)
get(1).get(EtaResult.Success.Eta::destination).isEqualTo(Station.TSY)
get(2).get(EtaResult.Success.Eta::destination).isEqualTo(Station.KOW)
get(3).get(EtaResult.Success.Eta::destination).isEqualTo(Station.HOK)
}
}
}
这次我们偷懒,我们把四笔班次的目的地 destination
都设定成不同车站,然後只检查车站就知道顺序是否正确。第二和第三笔班次是用来测试当时间相同时会不会按序号 sequence
排列。
另一个 test case 是测试按时间排序。跟刚才的 success, sort by direction
test case 一样,我们都是借 destination
判断排序是否正确。留意第一及第二笔的时间 time
都是相同,目的是检查结果是否有按序号 sequence
排列。
@Test
fun `success, sort by time`() = runBlockingTest {
coEvery {
repository.getEta(
Language.ENGLISH,
Line.TCL,
Station.OLY
)
} returns EtaResult.Success(
schedule = listOf(
EtaResult.Success.Eta(
direction = EtaResult.Success.Eta.Direction.DOWN,
platform = "1",
time = Instant.ofEpochSecond(1630700001),
destination = Station.HOK,
sequence = 2,
),
EtaResult.Success.Eta(
direction = EtaResult.Success.Eta.Direction.UP,
platform = "1",
time = Instant.ofEpochSecond(1630700001),
destination = Station.TUC,
sequence = 1,
),
EtaResult.Success.Eta(
direction = EtaResult.Success.Eta.Direction.UP,
platform = "1",
time = Instant.ofEpochSecond(1630700004),
destination = Station.TSY,
sequence = 2,
),
EtaResult.Success.Eta(
direction = EtaResult.Success.Eta.Direction.DOWN,
platform = "1",
time = Instant.ofEpochSecond(1630700003),
destination = Station.KOW,
sequence = 1,
),
),
)
val result =
useCase.invoke(Language.ENGLISH, Line.TCL, Station.OLY, GetEtaUseCase.SortBy.TIME)
expectThat(result).isA<EtaResult.Success>().get(EtaResult.Success::schedule).hasSize(4)
.and {
get(0).get(EtaResult.Success.Eta::destination).isEqualTo(Station.TUC)
get(1).get(EtaResult.Success.Eta::destination).isEqualTo(Station.HOK)
get(2).get(EtaResult.Success.Eta::destination).isEqualTo(Station.KOW)
get(3).get(EtaResult.Success.Eta::destination).isEqualTo(Station.TSY)
}
}
除了 EtaResult.Success
外,我们还会为其他情况写 test case,下面是 EtaResult.Incident
的 test case:
@Test
fun incident() = runBlockingTest {
val incident = EtaResult.Incident("Out of order!", "http://example.com")
coEvery {
repository.getEta(
Language.ENGLISH,
Line.TCL,
Station.OLY
)
} returns incident
val result =
useCase.invoke(Language.ENGLISH, Line.TCL, Station.OLY, GetEtaUseCase.SortBy.DIRECTION)
expectThat(result).isEqualTo(incident)
}
基本上都是比对 return value 是不是跟 EtaRepository
return 出来的一样,其余的 test case 都是同样写法,所以我就不逐一贴出来。完整的 test class 可以到 GitHub repo 查看。
下一篇我们会开始做 presentation layer。
<<: Proxmox VE 安装容器:Rocky Linux 8.4 及其它应用 (WordPress, Nextcloud, Odoo)
>>: [前端暴龙机,Vue2.x 进化 Vue3 ] Day22. Vue 旅游小帮手(完成)
最近一年内被问过的问题,在此不具名回复,以下以废宅的自问自答模式展开~~~ Q: 民营企业是否要遵循...
先在UI上做一个事件技能的锚点 修改一下ActionBattle_Action 修改一下算技能的距离...
虽然一讲到敏捷开发、DevOps 时就很常听到 CI/CD 这些词汇,不过到底什麽是 CI?又什麽是...
前言 align 主要是以交错轴为主,而昨天的 ustify-content 则是以主轴为主 ali...
在上一篇文章中为各位介绍ARFoundation/ARCore,今天我们要来制作魔术方块AR游戏。 ...